物联网之MQTT 协议
文章目录
Mqtt 协议框架
定义
MQTT是基于二进制消息的发布/订阅编程模式的消息协议,最早由IBM提出的,如今已经成为OASIS规范。由于规范很简单,非常适合需要低功耗和网络带宽有限的IoT场景
订阅(Subcription)
订阅包含一个主题过滤器(Topic Filter)和一个最大的服务质量(QoS)等级。订阅与单个会话(Session)关联。会话可以包含多于一个的订阅。会话的每个订阅都有一个不同的主题过滤器。
在iOS中的实际操作如下:
MQTTCFSocketTransport *transport = [[MQTTCFSocketTransport alloc]init];
//主机IP 地址
transport.host = @"";
transport.port = 10086;
MQTTSession *session = [[MQTTSession alloc]init];
session.transport = transport;
[session connectAndWaitTimeout:10.0];
[session connectWithConnectHandler:^(NSError *error) {
//Do some work
}];
//订阅某一个主题
[session subscribeToTopic:@"" atLevel:MQTTQosLevelAtLeastOnce subscribeHandler:^(NSError *error, NSArray<NSNumber *> *gQoss) {
if (error) {
}else{
}
}];
#pragma mark 从订阅的主题中收到消息
-(void)newMessage:(MQTTSession *)session data:(NSData *)data onTopic:(NSString *)topic qos:(MQTTQosLevel)qos retained:(BOOL)retained mid:(unsigned int)mid{
}
与请求和回应这种同步模式不同,发布/订阅模式解耦了发布消息的客户与订阅消息的客人之间的关系,这意味着发布者和订阅者之间并不需要直接建立联系.打个比方,你打电话给朋友,一直要等到朋友接电话了才能够开始交流,是一个典型的同步请求/回答的场景;而给一个好友邮件列表发电子邮件就不一样,你发好电子邮件该干嘛干嘛,好友们到有空了去查看邮件就是了,是一个典型的异步发布/订阅的场景。
这种模式带来的好处:
- 发布者和订阅者不必了解彼此,只要认识同一个消息代理
- 发布者和订阅者不需要交互,发布者无语等待订阅者确认
- 发布者和订阅者不需要同事在线,可以自由选择时间
主题(Topic Name)
附加在应用消息上的一个标签,服务端已知且与订阅匹配。服务端发送应用消息的一个副本给每一个匹配的客户端订阅。
MQTT是通过主题对消息进行分类的,本质上就是一个UTF-8的字符串,不过可以通过反斜杠表示多个层级关系。主题并不需要创建,直接使用就是了。
主题还可以通过通配符进行过滤。其中,+可以过滤一个层级,而#只能出现在主题最后表示过滤任意级别的层级。
举个例子:
building-b/floor-5:代表B楼5层的设备。
+/floor-5:代表任何一个楼的5层的设备。
building-b/#:代表B楼所有的设备。
注意,MQTT允许使用通配符订阅主题,但是并不允许使用通配符广播。
服务质量(Quality of Service,QoS)
在不同的场景下,Mqtt 支持3种不同级别的服务质量,保证了数据传输的可靠性
- 0级别:尽力而为。消息发送者会尽力发送消息,遇到意外并不会重试。
- 1级别:至少一次,消息接受者没有知会(回复)或者知会本身出现了丢失,消息发送者会再次发送以保证接受者至少会收到一次,可能会造成重复消息。
- 2级别:恰好一次。保证这种语义肯定会减少并发或者增加延时,不过丢失或者重复消息是不可接受的时候,级别2是最合适的
/**
Enumeration of MQTT Quality of Service levels
*/
typedef NS_ENUM(UInt8, MQTTQosLevel) {
MQTTQosLevelAtMostOnce = 0,
MQTTQosLevelAtLeastOnce = 1,
MQTTQosLevelExactlyOnce = 2
};
主题过滤器 (Topic Filter)
订阅中包含的一个表达式,用于表示相关的一个或者多个主题。主题过滤器可以使用通用符。
会话(Session)
客户端和服务端之间的状态交互。
控制报文 (MQTT Control Packet)
MQTT 规范定义了十四种不同类型的控制报文MQTT控制报文 MQTT Control Packects
链接:https://mcxiaoke.gitbooks.io/mqtt-cn/content/mqtt/03-ControlPackets.html
- CONNECT:客户端连接到MQTT代理
- CONNACK:连接确认
- PUBLISH:新发布消息
- PUBACK:新发布消息确认,是QoS 1给PUBLISH消息的回复
- PUBREC:QoS 2消息流的第一部分,表示消息发布已记录
- PUBREL:QoS 2消息流的第二部分,表示消息发布已释放
- PUBCOMP:QoS 2消息流的第三部分,表示消息发布完成
- SUBSCRIBE:客户端订阅某个主题
- SUBACK:对于SUBSCRIBE消息的确认
- UNSUBSCRIBE:客户端终止订阅的消息
- UNSUBACK:对于UNSUBSCRIBE消息的确认
- PINGREQ:心跳
- PINGRESP:确认心跳
- DISCONNECT:客户端终止连接前优雅地通知MQTT代理
发布(Publish)
NSData *data = nil;
[session publishData:data onTopic:@"" retain:NO qos:2];