基于MQTT协议的消息传输
为什么MQTT?
之前刚写了一篇关于socket的文章,为什么又来一个MQTT?因为MQTT协议就是socket接口实现的啊(socket和MQTT只是层级不一样而已),并且感觉发布/订阅模式非常棒,于是就想把MQTT也整明白些,做到在需要的时候选择合理的方式去实现。
MQTT的一些理解
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,主要用于物联网,据说国外也有公司用作服务器和手机客户端消息推送。它以轻便著称,更多MQTT优势特点看这里,官网在这里,官网上有很多的文档以及不同平台的示例代码等,可以自行下载。另,从这里(感觉比官网好)也一定有你想要的。(https://github.com/fusesource/mqtt-client 安卓)
发布订阅模式
使得消息发布者和订阅者不需要了解对方,发布者和订阅者不需要交互, 发布者无需等待订阅者确认而导致锁定,这和我们iOS中的通知是有区别的,iOS中的通知是同步的。。主题
订阅者像订阅通知一样订阅主题,发布者发布主题消息之后,MQTT代理就会将消息推送到相应的订阅者代理
作为一个中继站的感觉~,管理连接,处理消息发布和订阅的具体事宜。服务质量(Quality of Service –QoS)
- “至多一次”,消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。
- “至少一次”,确保消息到达,但消息重复可能会发生。
- “只有一次”,确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。
消息类型
MQTT协议下拥有14种不同的消息类型
MQTTConnect = 1, //客户端连接到MQTT代理
MQTTConnack = 2, //连接确认的消息
MQTTPublish = 3, //新发布消息
MQTTPuback = 4, //新发布消息确认
MQTTPubrec = 5, //消息发布 已记录
MQTTPubrel = 6, //消息发布 已释放
MQTTPubcomp = 7,// 消息发布完成
MQTTSubscribe = 8,//订阅
MQTTSuback = 9, //订阅回执
MQTTUnsubscribe = 10,//取消订阅
MQTTUnsuback = 11,//取消订阅的回执吧
MQTTPingreq = 12, //心跳消息
MQTTPingresp = 13,//确认心跳
MQTTDisconnect = 14 //客户端终止连接
MQTT是基于二进制消息发布订阅的消息协议,在我们编程的时候还会涉及到很多的字段,像keepAlive、cleanSession、will(遗愿)、willTopic、willMsg、willQoS、willRetain等诸多字段,那么具体的字段代表什么含义呢,那就要深入研究MQTT的报文,消息体结构,这里笔者就不做过多分析,关于报文消息体结构可以看这篇文章,详细的分析了各个字段的含义与用途,所以在这里关于MQTT消息遗嘱(遗愿就不过多讲述)。
关于MQTT的一些三方库的对比和使用
仔细深入才了解到MQTT协议其实使用还是非常广泛了,在GitHub上也有好多非常好的开源库。纸上得来终觉浅,笔者挨个去下载了这些个开源库自己跑了一下
- MQTTKit 以Mosquitto为代理,不知道Mosquitto是什么的自行谷歌,简洁、易用
- Marquette以Mosquitto为代理
- Moscapsule 以Mosquitto为代理
- Musqueteer以Mosquitto为代理
- MQTT-Client 原生实现,相对较复杂,还可以结合coredata使用,需者自取
- MqttSDK原生实现,用起来更方便
- CocoaMQTT 原生实现(swift)(辣眼睛,居然直接直接集成CocoaAsyncSocket,其他的底层实现都是corefoundation的cfsocket实现)
使用的话,和socket差别并不大,毕竟底层就是socket实现,多出来的无非就是上面列举的那些字段,正因为这些字段,使得MQTT会比socket优秀一点点(例如遗嘱等的存在,另外MQTT协议的消息体结构是很明确的,所以socket粘包等问题也能避免),至于socket通信代码可以看我这篇文章,至于MQTT代码就直接在GitHub搜索下载demo即可。
好吧!就到这里,hello MQTT~! 还是那句话,如您发现任何错误,欢迎留言指正~