“异步”是Pub/Sub模式的核心。Pub/Sub机制将消息发送者和接收者(订阅者)分离,实现了非等待的性质:每项服务现在只需要做自己的工作。这恰好也是对科技公司、金融机构、政府部门、足球队等多人团体中人际关系的完美解释。
代理(Broker)并不关心数据的具体内容(即有效载荷),只要其中包含主题(Topic),这样代理就可以将其转发给订阅者。
一个典型的MQTT 发布消息需要包括以下字段:
packetId:数据包的标识符。当消息被设置为发送时(即Qos>0),代理需要用这个标识符来定位要重新发送的消息。
topicName:主题名,其格式类似于Linux文件系统的目录。例如,我们可以将主题名设置为“shimokitazawa/beast/tadokoro”。
Qos:发布消息的服务质量等级。Qos通常有三个等级:至多一次 (0);至少一次 (1);只有一次 (2)。
retainFlag:当被设置为true时,代理将缓存上条主题消息;当有新订阅者出现时,代理会自动将该消息发送给他。
payload:消息的内容主体,格式不限。
dupFlag:当被设置为true时,则表示该消息是重复发送的。当Qos大于0时,代理会使用该标识符。
代理的工作很简单:代理收到消息后,开始读取Qos等级,并根据Qos将消息发送给订阅者。请注意,当消息被送到代理那里后,发布者的工作就完成了,任何剩余的工作都与发布者无关。
订阅者的工作就更简单了。订阅者告诉代理:“嘿,伙计,我订阅了这个主题,如果你收到这个主题的消息,就把它发给我”。
一个典型的MQTT 订阅消息需要包括以下字段:
packetId:它还是消息包的标识符。
以及一个主题和Qos组合列表:
qos_n:发给订阅者的预期主题Qos,该Qos作为订阅者接受该主题的最大Qos。例如,如果消息的Qos=2,但subscriber_a中主题的最大Qos=1,那么消息将以Qos=1的方式发送给该订阅者。
topic_n:订阅者所订阅的主题。
在收到订阅消息后,代理将向订阅者返回一条SUBACK消息,其中包括订阅者的元数据(即最大QOS)。一旦订阅者收到SUBACK信息,他们之间的通信就建立了。
要想退订主题,订阅者只需发送一条UNSUBSCRIBE消息,并注明要退订的主题(当然,UNSUBSCRIBE消息还是需要一个packetId),代理也将返回一条UNSUBACK消息给订阅者。
以上就是MQTT发布者、代理和订阅者在Pub/Sub模式下的工作方式。因为MQTT只是一个协议,我们需要定义代理如何识别订阅者——你可以只维护内存表来做,也可以选择用更复杂的方式来做,比如用多个ECC内存来处理一个受分布式锁定机制保护的复制容器化服务,从而来维护内存表。