美文网首页 ios零碎记录iOS技术资料iOS 细节大集合
iOS MQTT----MQTTClient实战-看这篇的就够了

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

作者: 今年我25 | 来源:发表于2016-12-05 16:24 被阅读20286次

    很久没有写东西了,半年搞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'

    第二步:


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


    第三步:

    导入 #import<MQTTClient/MQTTClient>

    1.设置地址和端口号.

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

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

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

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

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

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

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

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

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

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

    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就搞定,不需要写这么多.

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

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

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

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

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

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

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

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

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

    2.3 介绍两种监听方法:

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

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

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


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

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


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

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

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

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

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

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

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

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

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

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

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

    [self.mySession connectAndWaitTimeout:1];

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

    5.其他

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

    MQTT-EMQ服务器搭建

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

    相关文章

      网友评论

      • 中移OneMO模组:厉害,厉害!!了解更多物联网通信模组知识,获取贴身模组专业技术服务。关注中移模组,你想要的都在这里喔!
      • 小北风sky:你好,请问我在使用通配符#无效,是什么原因导致的?不用#就可以正常订阅。可以解答下吗?
      • 龙龙_caa0:楼主,app进入后台不就接不到数据了吗?这个没有APNS好用吧.
      • 大手2017:大神可以给我发个Demo吗。815144261@qq.com
      • 910b35f481df:有推送的demo吗?
      • 910b35f481df:有demo吗?
      • 神经蛙2007:楼主写得很详细,很清楚,语言生动有力,笔下有劲,我最近也要写一个配置网关的硬件,不知道MQTT与scoket哪个好使
      • 幻影刺客_小诺:博主,你好。请问mqtt要实现ssl的单向认证,怎么实现认证?谢谢。急急急,博主知道请告知我,谢谢。
      • 我叫大大虾米:1s 中收到几百个数据,cpu 100多,直接卡死怎么办
      • HotRay:我为什么 收不到服务器的数据?
      • 夏逸_40a9:建议代码部分 不要 用截图:flushed:
      • 我叫大大虾米:怎们发消息?
      • Mr_Zeng:你好,请问订阅主题的时候怎么判断是否订阅成功?
      • Jody526:请问有做过mqtt双向认证吗
        Jody526:http://www.jianshu.com/p/4676834ac3c4
      • JieGuan:您好,请问我的两个主题分别是gps和appraise,主题的URL我该怎么拼接呢 按上面的方法拼接不行呀!
      • 44d3387e09f3:求Demo
      • bc3d3e66fba3:想请问个问题,如果断开重连,你是怎么做的?
      • 小猪向天飞:作者有试到过就是用MQTTClient,会出现过通信慢的问题吗?怎么解决的呢?还有以及MQTTClient怎么配置SSL,谢谢!!!
      • 游尤馨伊:_topic订阅和发送不一直时,会断开连接 重连后 然后订阅能接受到数据,发送就发送不出去,有遇到过的没
      • 235a008fb19c:楼主问下 使用mqtt是不是要打开Push Notification选项?
      • e81cc2513886:怎么使用crt证书呢?
      • 敌敌味丶:楼主能共享下你封装的demo吗, 1256353923@qq.com,感谢!
      • 闲云悠鹤蝶恋舞:app进入后台后,就会收不到消息,但是打印的结果是还处于连接状态,在前台都能收到消息,请问有什么好的解决办法吗?
        闲云悠鹤蝶恋舞:@icelovery 目前还没有找到好的办法呢,可以换用第三方的推送
        6abebcb9be6a:同问这个情况 请问你解决了吗
        进入后台 或者锁屏 好像是socket关闭了 导致没有连接

        你的 问题怎么处理的
      • 髙师兄:楼主知道怎么添加证书吗?有没有相应的demo 邮箱1542683112@qq.com
      • james_w7:博主,能共享一下demo吗? 987292012@qq.com 非常感谢
      • MoneyLee:大神 求demo:heart_eyes:
        欧德尔丶胡:@MoneyLee 这里面对mqttclient封装了没?
        MoneyLee:@次草007 https://github.com/ReReReReReRe/Apollo-mqtt
        欧德尔丶胡:求demo学习下
      • keshiim:我司拿mqtt做IM功能,怎么看
        davisjy:你们的im写好了吗,求助
        davisjy:@Firmly_6c47 能加个QQ吗,我的549314170,我现在也需要做IM,没有思路:sob:
        49286b13fee1:我公司已经用这个 加了个 Hprose 中间件 做好了。好尴尬!
      • 番茄爱说冷笑话:楼主你好,我遇到的情况是 mqtt初始化链接服务器 然后mqtt停止了,但是没有订阅主题,像你上述的第二点问题,请问这个是服务器那边没有一直应答或者发数据所造成的吗?
      • Nothing_xy:请问怎样设置遗嘱,谢谢
        makemake:原谅我看到这里不厚道的笑出声:joy:
        Jody526:http://www.jianshu.com/p/4676834ac3c4
        5e5c8c458cfc:@_原来如此_ 鬼才会回答你。。
      • feng_dev:订阅topic的时候,那些宏是包括IP地址的还是不包括,还有那个斜杠有没有?
      • 倒影里浅笑:MQTTClient 没有断线重连的机制,但MQTTSession中有一个block是监听连接状态的connectionHandler,当连接状态发生改变时就会执行block,而block的参数中有连接状态,根据这个状态就可以判断是否连接上,这样的话就不需要用定时器处理了吧
      • keepin:楼主 我遇到你所说的那个问题 我监听重连之后 怎么不返回数据。。求解
      • 16bac4d02dff:CKHttpTools有demo吗????
      • shushuzhen:最近就是用mqtt,遇到一些作者说的那些。看一下有了更深层的理解,感谢分享,嘻嘻
        3c4403df0e9d:哥们,有demo吗 发我一份 谢谢!
      • FongG:使用mqtt可以达到像ios中网易云音乐播放器一样在后台持续运行的效果吗?
        依然丶冷枫:网易云音乐能在后台持续运行,是因为苹果允许音乐类App常驻后台。
      • TigerNong:你再写这个MQTT的时候,有没有出现当程序没有退出,但是放置在前台一段时间(超过10分钟)后,当再次进入到前台的时候,MQTT会主动断开!?
      • 74e208c38b22:厉害! 可以发一下demo吧,谢谢!
      • 幸福的李雨龙:安装说明书👏👏👏
      • mark666:我的文章扩展

      本文标题:iOS MQTT----MQTTClient实战-看这篇的就够了

      本文链接:https://www.haomeiwen.com/subject/efeopttx.html