MQTT Part 3 客户端,中间人(Broker),建立连接

本文翻译自http://www.hivemq.com/blog/mqtt-essentials-part-3-client-broker-connection-establishment

未经允许,不得转载

介绍

正如我们所了解的,MQTT解耦了发布者和订阅者,所以任何客户端都只与中间人(broker)建立连接。在深入了解连接细节之前,让我们先搞清楚客户端和中间人的概念。

客户端

我们所说的客户端泛指MQTT的客户端,包含发布者和订阅者,分别负责发布消息和订阅消息。(通常情况下,一个MQTT实体同时具备发布者和订阅者两重功能)。任何包含了MQTT运行库并且通过任意网路类型连接到MQTT broker的且具备微控制器的设备都称为MQTT客户端。它可以是一个用于测试的小型设备,包含一个小型计算机系统,同时可以接入无线网络,最重要的是其支持TCP/IP协议从而允许MQTT在其上运行。在客户端上实现MQTT协议非常直观方便,基于此,可以说MQTT非常适合小型设备。MQTT客户端运行库支持大部分编程语言和平台,例如,Android,Arduino,C,C++,C#,Go,iOS,Java,Javascript,.Net。完整的支持列表可以参考MQTT wiki

中间人(Broker)

和MQTT客户端协作的另一部分是MQTT broker,其被称为发布/订阅协议的心脏部分,根据具体的实现不同,一个broker可以支持数以千计的客户端并发连接。broker的主要职责是接受所有消息,并将其过滤后分发给不同的消息订阅者。它也可以根据订阅内容和未送达的消息来保持持久的会话。broker的另一个职责是验证和授权客户端。在大多数时候,broker是可扩展的,我们可以将其整合进后台系统,整合进系统显得尤为重要,因为大多数时候,broker只是一个网络通信系统的组件。我们之前的一篇文章提到订阅所有消息并不是很好的选择。总而言之,broker是一个中心交换机,交换所有数据。因此高扩展性,可集成到后台系统,易于监控当然还包括不出错误对broker来说尤为重要。HiveMQ的插件系统提供了良好的解决方案。

MQTT连接

MQTT协议基于TCP/IP,并工作在其上层,所有的客户端和broker都需要支持TCP/IP协议。


MQTT连接只发生在客户端和broker之间,客户端并不直接与客户端连接。连接开始于一个客户端给broker发送一条CONNECT消息。broker回复一条CONNACK和状态码。一旦连接建立,broker将保持连接开放,直至客户端发送断开连接命令或者连接本身丢失。

MQTT通过NAT建立连接

通常情况下,MQTT客户端都在一个NAT路由器下,为了能够使一个局域网ip(例如192.168.x.x)与一个公网ip通信。正如前文提到的,MQTT客户端第一步是发送一个CONNECT消息,所以客户端在路由器下没有任何问题,因为broker有一个公网ip地址并且连接将会保持开放状态以允许在连接初始化后进行双向的发送和接受消息。

客户端以一个CONNECT消息初始化连接

让我们来看一下MQTT连接消息,正如前面提到的,客户端发送消息给broker以初始化连接。如果CONNET消息是畸形的,或者由建立socket连接到发送消息中间等待的时间过长,broker都会关闭连接。这是一个较好的避免恶意客户端攻击服务器的处理方式。一个正常的客户端将会按照下面的内容发送连接消息。


此外,CONNECT消息还包含了一些其他信息,这些信息与MQTT库的制定者有更多关系,实际使用者则不必关心,如果你感兴趣,请参考官方MQTT 3.1.1 说明
下面让我们逐个了解一下这些信息的含义。

ClientId

ClientId是连接到broker的每个MQTT客户端的唯一标识符。根据场景不同,broker制定的ID规则也可以不同。broker使用此标识符来识别客户端以及客户端的当前状态。如果你不需要broker记录客户端的状态,也可以发送一个空的ClientId,这样将会创建一个无状态的连接,此功能适用于MQTT 3.1.1版本。这样做的一个前提条件是cleanSession字段需要置为true,否则连接将会被拒绝。

Clean Session

Clean session 字段表明客户端是否想与broker建立持久的会话。一个持久的会话(cleanSession为false)意味着,当使用QoS级别为1或2时,broker将会存储所有的客户端订阅的消息,和尚未送达的消息。如果cleanSession为true时,broker不会存储任何客户端订阅的消息,并会将之前所存的内容清空。

Username/Password

MQTT允许发送用户名和密码来鉴定和授权客户端身份。然而,如果未使用TLS加密,用户名和密码将会以明文的方式传输。我们强烈建议使用安全传输协议来传输用户名和密码。HiveMQ broker也支持使用SSL验证客户端身份,此时用户名和密码不再必须。

Will Message(遗嘱)

遗嘱是MQTT的一大特色,它允许broker在发现一台设备意外断开时发送通告给其他相关设备。客户端在建立CONNECT连接时会将遗嘱打包在消息体里。如果这个客户端在没有通知的情况下意外断开连接,broker将会发送遗嘱消息给其他关联设备。我们将会在单独一章讨论此话题。

KeepAlive(心跳)

心跳是指客户端周期性地发送PING请求给broker,broker也会应答此心跳,这种机制可以保证双方知道对方是否还在线。我们将会在单独一章讨论此话题。

最主要的是所有消息都由MQTT客户端向broker建立连接,有一些定制化的库文件还会附加其他选项,例如规定消息如何排序和存储等。

Broker以CONNACK消息应答

当broker收到一个CONNECT消息时,broker有义务应答一个CONNACK消息,CONNACK只包含两个数据字段,一个是Session present flag(当前会话标志),另一个是Return code(返回码)。

Session Present Flag(当前会话标志)

当前会话标识可以表明broker是否在之前已经和客户端建立过持久会话。如果客户端连上来并且将cleanSession字段置为true,那么当前会话标志将始终为false,因为会话都已经被清空了。如果客户端在连上来时将cleanSession置为false,那么flag的状态决定于当前针对此客户端是否有可用的会话。如果有已有存储的会话消息,那么false将会为true,否则为false。这个flag标志在MQTT 3.1.1中被添加,以帮助客户端来确定是否需要订阅主题或判断当前是否有待处理的消息。

Return Code(返回码)

第二个字段是连接告知标志,它通知客户端,连接是否正常或出现了什么问题


在下表中,我们可以看到所有返回码代表的含义

Return Code 含义
0 接受连接
1 拒绝连接,不能被接受的协议版本
2 拒绝连接,ID无效
3 拒绝连接,服务器不可用
4 拒绝连接,错误的用户名和密码
5 拒绝连接,未经授权

更多的详细解释可以参见官方MQTT说明

后续

你也许会问,在没有消息发送的时候,MQTT怎样保持连接?或者怎样知道连接丢失?请耐心等待,我们会在后面的文章中详细介绍。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容