Osheep

时光不回头,当下最重要。

iOS MQTT----MQTTClient实战-看这篇的就够了

很久没有写东西了,半年搞1个半app,2个ipad项目,人已疯。。。。

今天在重构代码,总结一下:MQTT的使用和坑

MQTT 是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和致动器(比如通过Twitter让房屋联网)的通信协议 ———————-百度词条解释


应用场景

MQTT是一个设计得非常出色的传输层协议,在移动消息、物联网、车联网、智能硬件甚至能源勘探等领域有着广泛的应用。1个字节报头、2个字节心跳、消息QoS支持等设计,非常适合在低带宽、不可靠网络、嵌入式设备上应用。

不同的应用有不同的系统要求,用户使用emqttd消息服务器前,可以按自己的应用场景进行测试,而不是简单的连接压力测试:

Android消息推送: 推送消息广播测试。

移动即时消息应用: 消息收发确认测试。

智能硬件应用: 消息的往返时延测试。

物联网数据采集: 并发连接与吞吐测试

其他的不多说,有很多资料,一般常用的有两个MQTT

1.MQTTKit

2.MQTTClient

两个都用过,不过目前用的是MQTTClient,在Ios10出来后更新了一版,经常维护;

MQTTKit,这个貌似很久没更新了,也不多说

首先明确一下你拿这个东西干嘛的,拿我做的app来说:

在地图页面,请求历史数据,然后通过mqtt订阅主题,获取终端的返回的数据,然后实时更新数据,效果就类似于打车软件的样子,实现实时监控数据等功能。


第一步:安装MQTT

MQTT-Client-Framework   GitHub地址

用cocopod的直接,下载就好   pod ‘MQTTClient’

第二步:

《iOS MQTT----MQTTClient实战-看这篇的就够了》


安装好之后就这样,每个类一看知道就是干嘛,直接上代码详细说

第三步:

导入 #import<MQTTClient/MQTTClient>

1.设置地址和端口号.

《iOS MQTT----MQTTClient实战-看这篇的就够了》

2.设置mqtt的账号和密码,同样找好基友要

《iOS MQTT----MQTTClient实战-看这篇的就够了》

3. 最后订阅主题,这个地方看了很多人写的博客,假设你的主题很多比如5个,10个,使用线程处理,这样也是可以的,但是不是最优化的方式,后面会详细说明,对了mqtt是可以同时订阅多个主题的,很多资料都未说明.

这个地方用了枚举,主要是为了判断订阅主题,来处理回调的数据

//注意:订阅主题不能放到子线程进行,否则block不会回调

//下面这些都是自己封装过得

//主题格式          @“$IOT/haha/datapoint/motor_control”

《iOS MQTT----MQTTClient实战-看这篇的就够了》

//如果不封装就是这样的

《iOS MQTT----MQTTClient实战-看这篇的就够了》

这样就实现了主题订阅,订阅成功后会有log,一堆信息,这样的

《iOS MQTT----MQTTClient实战-看这篇的就够了》

第四步:实现Session代理方法,处理数据

《iOS MQTT----MQTTClient实战-看这篇的就够了》

在代理方法中,就可以得到对应的数据,在这里说明一下

1.如果你订阅的主题只有一个,那么你不判断也是可以的,但是如果有多个主题,你需要判断,返回的哪个对应的主题,然后才能处理数据。

2.你订阅主题假如是这样的    @“$IOT/haha/datapoint/motor_control”  ,那么在处理数据时,你判断“motor_control”字符串就可以找到对应的数据,判断最后的参数就行,看截图就明白了.

3.然后拿到你的数据,你想干嘛就干嘛.


(⊙o⊙)…,到这里基本的就完了,那是不可能的,我发现很多资料写到这里就完了,还有很多的重点没说明,不然整理东西就没意义了.



可能大家用处不一样的,有人会碰到,有人不会,在这里说明一下,可能会遇到的问题:

1.先说常用的属性,如果你一直把mqtt开着,你不处理,那么mqtt一直会有数据返回,我这边就是1秒一次,然后一堆数据….

在刚开始的时候,初始化了 MQTTSession 的对象,看截图

[self.mySession disconnect] 断开连接 对应的就是 [self.mySession connect] 重新连接

如果不需要mqtt了,记得close,不然mqtt还会返回数据.

当然这个截图,只是全部举例说明,如果不用mqtt直接,close就搞定,不需要写这么多.

《iOS MQTT----MQTTClient实战-看这篇的就够了》

2.在正常情况下,你的mqtt成功订阅了主题,那么它会一直在监听服务器是否有数据返回,但是有的时候嘛,你会遇到下面这中情况,mqtt停止了,当然排除你自己 close的情况外.

《iOS MQTT----MQTTClient实战-看这篇的就够了》

这种情况就很坑爹啦,你用mqtt的目的是啥,就是要实时监控嘛。。。。

在我查询的资料中有几种解释:

前提是你家的服务器一直在发送数据,而不是停掉了

2.1 你的clientID,没有设置,简单说明,你有一个账号是老王,那么你登录了,你的同事也登录了,这个时候,mqtt会自动掉线。

self.mySession.clientId 有这个属性,我咨询过后台,说移动端要设置,设置成功就可以避免,但是如果你用的是,MQTTClient 这个,完全不用,因为别人已经处理好了,可以自己点击进去看看,那么如果你用的是其他的第三方,clientId需要取随机数,不能相同.

2.2 碰到上面这个问题咋办呢,MQTTClient 没有断线重连的机制,也可能是我没找到,哪位小伙伴看到了也麻烦告诉我一声.

这个时候,你需要监听消息的状态,就可以处理了,来看看,self.mySession.status的值

《iOS MQTT----MQTTClient实战-看这篇的就够了》

在上面也写到了,如果你使用disconnect\connect,那么消息的状态最终都会输出第五个MQTTSessionStatusClosed.

2.3 介绍两种监听方法:

2.3.1  KVO    在创建MQTTSession对象的时候,添加就可以了

《iOS MQTT----MQTTClient实战-看这篇的就够了》

《iOS MQTT----MQTTClient实战-看这篇的就够了》

这样只要消息关闭了,那么mqtt会立即重连;但是会有一个问题,如果你的mqtt只是部分页面用,离开这个页面之后,mqtt还会继续监听,不停的创建对象,上面解释过了,消息状态最终都是MQTTSessionStatusClosed.

2.3.2 目前我在用就是定时器,用定时器处理消息状态

《iOS MQTT----MQTTClient实战-看这篇的就够了》

《iOS MQTT----MQTTClient实战-看这篇的就够了》

好处就是,离开页面的时候,mqtt关闭,定时器也关闭,不会导致kvo那种情况出现,坏处暂时没发现.

这样就可以让mqtt一只处于监控的状态下了.


3.关于MQTT一次性订阅多个主题,每个mqtt框架都可以。

假如你要一次性订阅10个主题,那么你不得写十次么,完全不用这样,现在介绍一个更简单的办法,

你只需要更改一个地方就可以了,主题URL

上面我写的主题格式是这样的

//主题格式          @“$IOT/haha/datapoint/motor_control”

现在你只需要把主题的URL  改成这样  @”$IOT/haha/#”

MQTT主题(Topic)支持’+’, ‘#’的通配符,’+’通配一个层级,’#’通配多个层级(必须在末尾)

解释一下,#表示,haha下面的所有主题,假如你有10个主题,你这样就可以一次性订阅完成,然后你在返回的数据中,判断对应的主题处理数据就可以了.

代码中就可以把其它的注释掉.

《iOS MQTT----MQTTClient实战-看这篇的就够了》

话又说回来,一个页面你只用到一个主题的内容,你难道也这样写嘛,所以一切看实际情况。

4.最后说一个,MQTT超时时间设置的问题.

[self.mySession connectAndWaitTimeout:1];

MQTT在网络情况不太好/接收不到服务器数据时,容易导致线程卡住,你懂得,什么都不能点了,建议把这里的时间设置小一点.

5.其他

最最后,补充一个网站,后台搭建mqtt服务器,移动端使用原理介绍都可以用,MQTT介绍的很全面了,深入了解的可以看看,有swift和oc的版本,这个我没用过,原理一样.

MQTT-EMQ服务器搭建

6.DEMO 下载地址    暂无,弄好了再传

点赞