01月28, 2019

MQTT协议之发布订阅

介绍了MQTT如何创建客户端与服务端之间的连接之后,接下来就是如何进行消息的传递,本篇博客将进一步介绍MQTT的发布,订阅细节。

消息发布

每个消息必须包含一个主题,通过该主题服务端将消息投递给那些对该主题感兴趣的客户端。消息的具体内容是通过二进制的形式进行传递。MQTT是对消息内容无感知的,客户端可以发送任何格式的数据,比如二进制数据,文本数据,XML数据或者Json数据等。

Publish消息的格式如下

发布的消息格式

主题名称

主题是通过斜杠分隔的字符串组成的分层结构,例如 "myhome/livingroom/temperature"

服务质量

服务质量决定了消息投递到目标的保证等级。服务质量分三个等级,0,1,2。0表示消息最多投递一次,如果失败了也不会进行重试。1表示消息最少投递一次,消息如果接收端没有明确收到(返回acked),则会持续重试发送。2表示消息有且投递一次,这里指的有且只有一次,指的是消息从接收者向下投递该消息只有一次。

预留标志

预留标志决定了该消息是否保留为该主题最新的消息。当一个新客户端订阅该主题时,将会收到该主题最新的预留消息。预留消息针对一个主题最多有一条,可以没有。

消息体

消息体为消息的具体内容,MQTT是不感知消息内容的,所以用户可以任意传递消息。

重复字段

当消息的服务质量大于0的时候,消息进行重试的时候设置该字段。

消息订阅

如果没有客户端订阅主题,向主题发送消息,将不会有任何客户端收到该消息。客户端发送订阅请求到服务端订阅相应的主题。

Subscribe消息的格式如下

订阅消息格式

报文唯一标识

消息报文的唯一标识,服务端和客户端分别设置自己的PacketId,标识不具有全局唯一性,只要会话单向唯一即可。

订阅列表

一次订阅可以订阅多个主题。每个订阅操作需要包含订阅的主题名称和一个想要的服务质量。订阅时的主题可以是包含通配符的形式。如果订阅信息有重叠的,服务端将按照最大的服务质量来投递消息。

消息订阅确认

客户端请求订阅主题之后,服务端将回复suback。 消息包含和订阅相同的报文唯一标识符,以及一组返回码,如下所示

suback消息格式

报文唯一标识

该报文唯一标识,需要同相应的订阅请求保持一致。

返回码

返回码对应订阅请求中的Qos-topic的列表,一对一的确认订阅的结果。如果成功则返回相应的服务质量(0/1/2),如果失败了则返回#ff(128).

客户端发起订阅,收到订阅成功后,接下来发送到该主题的消息,这个客户端都能正常接收到。

取消订阅

讲完订阅,就要讲如何能够部关注某个主题。 取消订阅的报文如下所示,主要包含一个唯一标识符和一组待取消的主题列表。

取消订阅消息格式

取消订阅确认

取消订阅的返回只包含一个和取消订阅的相同的唯一标识符。无论之前是否订阅了该主题,取消订阅的确认都会正常返回。

总结

MQTT消息传递是通过订阅相应的主题,然后发布消息到相应主题的形式实现的。

发布之前无须进行主题的创建和维护,也不需要关心是否又客户端在订阅相应的主题。

发布订阅很好的解耦了发布者和订阅者,使得更加容易进行各种业务场景的组合,比如实现分组,实现广播等。

发布订阅同样也带来了一个问题,发布者如果希望能够感知到订阅者收到消息之后的回馈,只能通过业务层来实现,比如订阅者收到之后,再通过另外一个主题发布结构给发布者。

本文链接:https://www.opsdev.cn/post/subpub.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。