关闭

MQTT协议实现(一)

标签: iosMQTT协议socket
3097人阅读 评论(0) 收藏 举报
分类:

MQTT协议实现(一)

11年的时候,记录写过一篇文章《采用MQTT协议实现android消息推送》,那个时候,只是为了实现推送的功能,没有仔细阅读过MQTT协议的内容。最近看同事又重新提起这个协议,于是就心血来潮去实现一下。MQTT协议是在tcp协议之上的,是基于TCP/IP的一个应用协议,正好可以验证一下自己之前整理的基于tcp的RHSocket框架。

MQTT协议简述

MQTT(Message Queue Telemetry Transport),遥测传输协议,提供订阅/发布模式,更为简约、轻量,易于使用,针对受限环境(带宽低、网络延迟高、网络通信不稳定),对于移动互联网的场景的消息推送十分有效。

特点如下:

1.使用发布/订阅消息模式,提供一对多的消息发布,接触应用程序耦合。

2.对负载内容屏蔽的消息传输。

3.使用TCP/IP提供网络连接。

4.有三种消息发布服务质量:“至多一次”,“至少一次”,“只有一次”

5.传输数据小(最小固定长度的头部是2个字节),协议交换最小化,以降低网络流量。

具体的协议内容可以从ibm网站学习:http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html

官方下载地址: http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/MQTT_V3.1_Protocol_Specific.pdf

也可以直接阅读网友的博客:http://www.blogjava.net/yongboy/archive/2014/02/07/409587.html

阅读了MQTT的协议内容后,会发现它其实和前面RHSocket框架中提到过的自定义协议内容类似,

协议头(固定头部fixedheader,可变头部variableheader)+内容(内容载体payload)。

固定头部(第一个固定协议字节,可变长度字节)

第一个字节(8位)

固定携带了4个数据内容,message type,dup flag,QoS level,retain。

0 1 2 3 4 5 6 7

第0到3位,这4个bit是message type。

第4位,这1个bit是dup flag。

第5和6位,这2个bit是QoS level。

第7位,这1个bit是retain,预留位。


程序定义如下:

/** message type */
typedef NS_ENUM(UInt8, RHMQTTMessageType) {
    RHMQTTMessageTypeConnect = 1,           //client request to connect to server
    RHMQTTMessageTypeConnAck = 2,           //connect acknowledgment
    RHMQTTMessageTypePublish = 3,           //publish message
    RHMQTTMessageTypePubAck = 4,            //publish acknowledgment
    RHMQTTMessageTypePubRec = 5,            //publish received (assured delivery part 1)
    RHMQTTMessageTypePubRel = 6,            //publish release (assured delivery part 2)
    RHMQTTMessageTypePubComp = 7,           //publish complete (assured delivery part 3)
    RHMQTTMessageTypeSubscribe = 8,         //client subscribe request
    RHMQTTMessageTypeSubAck = 9,            //subscribe acknowledgment
    RHMQTTMessageTypeUnsubscribe = 10,      //client unsubscribe request
    RHMQTTMessageTypeUnsubAck = 11,         //unsubscribe acknowledgment
    RHMQTTMessageTypePingReq = 12,          //ping request
    RHMQTTMessageTypePingResp = 13,         //ping response
    RHMQTTMessageTypeDisconnect = 14,       //client is disconnecting
    RHMQTTMessageTypeReserved = 15          //reserved
};

/** QoS(Quality of Service,服务质量) */
typedef NS_ENUM(UInt8, RHMQTTQosLevel) {
    RHMQTTQosLevelAtMostOnce = 0,               //至多一次,发完即丢弃,<=1
    RHMQTTQosLevelAtLeastOnce = 1,              //至少一次,需要确认回复,>=1
    RHMQTTQosLevelExactlyOnce = 2,              //只有一次,需要确认回复,=1
    RHMQTTQosLevelReserved = 3                  //待用,保留位置
};


可变长度字节(为可变头部和协议内容的长度之和,动态计算获得,最小为1个字节0x7F,最大为4个字节0xFF,0xFF,0xFF,0x7F)

0xff 0xff 0xff 0x7f
如果可变头部和包体内容的数据长度之和大于127,则可变长度字节数需要加长,从原来的1个字节,变为可容纳的字节数,最大为4个字节。

至于为什么不是0xff,http://www.blogjava.net/yongboy/archive/2014/02/07/409587.html中有说明,是MQTT协议规定所致。

可变头部

可变头部,协议中不同的命令,携带的数据内容也不同。http://www.blogjava.net/yongboy/archive/2014/02/09/409630.html

后续通过程序实现分别说明。


包体内容

同上。

具体的内容,已经提供了学习连接,我就不拷贝了,哈哈。

阅读相关的内容后,应该大概了解MQTT协议的字段定义了,下一篇我们从MQTT协议的连接入手,来一步步的学习。

相关代码已经提交到github,https://github.com/zhu410289616/RHMQTTKit



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:121249次
    • 积分:1007
    • 等级:
    • 排名:千里之外
    • 原创:13篇
    • 转载:1篇
    • 译文:0篇
    • 评论:39条
    文章分类
    最新评论