打印

一起看看这个go语言实现的mqtt

[复制链接]
楼主: keer_zu
手机看帖
扫描二维码
随时随地手机跟帖
21
keer_zu|  楼主 | 2017-3-7 15:45 | 只看该作者 |只看大图 回帖奖励 |倒序浏览

是的,哈哈

使用特权

评论回复
22
zhuyemm| | 2017-3-7 21:50 | 只看该作者
强烈支持楼主ing……

使用特权

评论回复
23
keer_zu|  楼主 | 2017-3-7 22:06 | 只看该作者
zhuyemm 发表于 2017-3-7 21:50
强烈支持楼主ing……

谢谢。

使用特权

评论回复
24
Joseph唐| | 2017-3-7 22:11 | 只看该作者
这种语言怎么跟C++很相似

使用特权

评论回复
25
keer_zu|  楼主 | 2017-3-7 22:20 | 只看该作者
Joseph唐 发表于 2017-3-7 22:11
这种语言怎么跟C++很相似

比c++容易,没有malloc和free。天然支持并发。

使用特权

评论回复
26
keer_zu|  楼主 | 2017-3-8 08:46 | 只看该作者
通过 github.com/huin/mqtt项目解析
我们了解到本项目所调用的 github.com/huin/mqtt 主要解决了消息的解析与构建。
接下来我们继续分析本项目。

使用特权

评论回复
27
ddllxxrr| | 2017-3-8 09:50 | 只看该作者
感觉有点高难

使用特权

评论回复
28
keer_zu|  楼主 | 2017-3-8 09:59 | 只看该作者

也还好啦,看两个项目,习惯就好了。这里面没有复杂的结果,没有难懂的算法,对着mqtt协议(上面都有)多看一下就行了。

使用特权

评论回复
29
keer_zu|  楼主 | 2017-3-8 14:04 | 只看该作者
继续下面的分析之前,先一起学习一下 第四章 操作行为 Operational behavior










使用特权

评论回复
30
beam92| | 2017-3-8 15:59 | 只看该作者
路过

使用特权

评论回复
31
keer_zu|  楼主 | 2017-3-8 16:25 | 只看该作者
mqtt协议对网络的要求:
网络连接 Network Connections

MQTT协议要求基础传输层能够提供有序的、可靠的、双向传输(从客户端到服务端 和从服务端到客户端)的字节流。

    非规范评注

    MQTT 3.1使用的传输层协议是 [RFC793] 定义的TCP/IP协议。下面的协议也支持:

    TLS协议 [RFC5246]
    WebSocket协议 [RFC6455]

    非规范评注

    TCP端口8883和1883已在IANA注册,分别用于MQTT的TLS和非TLS通信。

无连接的网络传输协议如UDP是不支持的,因为他们可能会丢失数据包或对数据包重排序。
这里规定了mqtt对网络连接的要求,有三种可以满足需要,包括TCP/IP。UDP不支持

其中,TLS是传输层安全协议(Transport Layer Security,缩写:TLS),及其前身安全套接层(Secure Sockets Layer,缩写:SSL)是一种安全协议,目的是为互联网通信提供安全及数据完整性保障。
一个go的实现例子: 使用Go实现TLS 服务器和客户端


使用特权

评论回复
32
keer_zu|  楼主 | 2017-3-8 16:28 | 只看该作者
keer_zu 发表于 2017-3-8 16:25
mqtt协议对网络的要求:
这里规定了mqtt对网络连接的要求,有三种可以满足需要,包括TCP/IP。UDP不支持

对网络故障的处理:
网络故障

在任何网络环境下,都会出现一方连接失败,比如离开公司大门那一刻没有了WIFI信号。但持续连接的另一端-服务器可能不能立即知道对方已断开。类似网络异常情况,都有可能在消息发送的过程中出现,消息发送出去,就丢失了。

MQTT协议假定客户端和服务器端稳定情况一般,彼此之通信管道不可靠,一旦客户端网络断开,情况就会很严重,很难恢复原状。

但别忘记,很多客户端会有永久性存储设备支持,比如闪存ROM、存储卡等,在通信出现异常的情况下可以用于保存关键数据或状态信息等。

总之,异常网络情况很复杂,只能小心处理之。

使用特权

评论回复
33
keer_zu|  楼主 | 2017-3-8 16:31 | 只看该作者
QoS leavel 和 消息重传机制关系:
消息重发策略

在QoS > 0情况下,PUBLISH、PUBREL、SUBSCRIBE、UNSUBSCRIBE等类型消息在发送者发送完之后,需要等待一个响应消息,若在一个指定时间段内没有收到,发送者可能需要重试。重发的消息,要求DUP标记要设置为1.

等待响应的超时应该在消息成功发送之后开始算起,并且等待超时应该是可以配置选项,以便在下一次重试的时候,适当加大。比如第一次重试超时10秒,下一次可能为20秒,再一次重试可能为60秒呢。当然,还要有一个重试次数限制的。

还有一种情况,客户端重新连接,但未在可变头部中设置clean session标记,但双方(客户端和服务器端)都应该重试先前未发送的动态消息(in-flight messages)。客户端不被强制要求发送未被确认的消息,但服务器端就得需要重发那些未被去确认的消息。
QoS level决定的消息流

QoS level为Quality of Service level的缩写,翻译成中文,服务质量等级。

MQTT 3.1协议在"4.1 Quality of Service levels and flows"章节中,仅仅讨论了客户端到服务器的发布流程,不太完整。因为决定消息到达率,能够提升发送质量的,应该是服务器发布PUBLISH消息到订阅者这一消息流方向。

使用特权

评论回复
34
keer_zu|  楼主 | 2017-3-8 18:35 | 只看该作者
各个级别的详细情况:

QoS level 0

至多发送一次,发送即丢弃。没有确认消息,也不知道对方是否收到。
Client         Message and direction         Server
QoS = 0         PUBLISH
---------->         Action: Publish message to subscribers then Forget
Reception: <=1

针对的消息不重要,丢失也无所谓。

网络层面,传输压力小。




















QoS level 1

所有QoS level 1都要在可变头部中附加一个16位的消息ID。

SUBSCRIBE和UNSUBSCRIBE消息使用QoS level 1。

针对消息的发布,Qos level 1,意味着消息至少被传输一次。

发送者若在一段时间内接收不到PUBACK消息,发送者需要打开DUB标记为1,然后重新发送PUBLISH消息。因此会导致接收方可能会收到两次PUBLISH消息。针对客户端发布消息到服务器的消息流:
Client         Message and direction         Server
QoS = 1
DUP = 0
Message ID = x

Action: Store message
        PUBLISH
---------->        
Actions:

    Store message
    Publish message to subscribers

    Delete message

Reception: >=1
Action: Discard message         PUBACK
<----------        
Message ID = x

针对服务器发布到订阅者的消息流:
Server         Message and direction         Subscriber
QoS = 1
DUP = 0
Message ID = x         PUBLISH
---------->        
Actions:

    Store message
    Make message available                        

Reception: >=1

        PUBACK
<----------        
Message ID = x

发布者(客户端/服务器)若因种种异常接收不到PUBACK消息,会再次重新发送PUBLISH消息,同时设置DUP标记为1。接收者以服务器为例,这可能会导致服务器收到重复消息,按照流程,broker(服务器)发布消息到订阅者(会导致订阅者接收到重复消息),然后发送一条PUBACK确认消息到发布者。

在业务层面,或许可以弥补MQTT协议的不足之处:重试的消息ID一定要一致接收方一定判断当前接收的消息ID是否已经接受过

但一样不能够完全确保,消息一定到达了。












QoS level 2

仅仅在PUBLISH类型消息中出现,要求在可变头部中要附加消息ID。

级别高,通信压力稍大些,但确保了仅仅传输接收一次。

先看协议中流程图,Client -> Server方向,会有一个总体印象:
Client         Message and direction         Server
QoS = 2
DUP = 0
Message ID = x

Action: Store message
        PUBLISH
---------->         Action(a) Store message

or
Actions(b):

    Store message ID
    Publish message to subscribers

          PUBREC
<----------         Message ID = x
Message ID = x         PUBREL
---------->         Actions(a):

    Publish message to subscribers
    Delete message

or
Action(b): Delete message ID
Action: Discard message         PUBCOMP
<----------         Message ID = x

Server -> Subscriber:
Server         Message and direction         Subscriber
QoS = 2
DUP = 0
Message ID = x         PUBLISH
---------->         Action: Store message
          PUBREC
<----------         Message ID = x
Message ID = x         PUBREL
---------->         Actions:

    Make message available                        


        PUBCOMP
<----------         Message ID = x

Server端采取的方案a和b,都包含了何时消息有效,何时处理消息。两个方案二选一,Server端自己决定。但无论死采取哪一种方式,都是在QoS level 2协议范畴下,不受影响。若一方没有接收到对应的确认消息,会从最近一次需要确认的消息重试,以便整个(QoS level 2)流程打通。
消息顺序

消息顺序会受许多因素的影响,但对于服务器程序,必须保证消息传递流程的每个阶段要和开始的顺序一致。例如,在QoS level 2定义的消息流中,PUBREL流必须和PUBLISH流具有相同的顺序发送:
Client         Message and direction         Server
          PUBLISH 1
---------->
PUBLISH 2
---------->
PUBLISH 3
---------->
         
          PUBREC 1
<----------
PUBREC 2
<----------
         
          PUBREL 1
---------->
         
          PUBREC 3
<----------
         
          PUBREL 2
---------->
         
          PUBCOMP 1
<----------
         
          PUBREL 3
---------->
         
          PUBCOMP 2
<----------
PUBCOMP 3
<----------
         

流动消息(in-flight messages)数量允许有一个可保证的效果:

    在流动消息(in-flight)窗口1中,每个传递流在下一个流开始之前完成。这保证消息以提交的顺序传递
    在流动消息(in-flight)大于1的窗口,只能在QoS level内被保证消息的顺序

使用特权

评论回复
35
chendata| | 2017-3-9 20:04 | 只看该作者
楼主加油!

使用特权

评论回复
36
chendata| | 2017-3-9 20:07 | 只看该作者
renxiaolin 发表于 2017-3-7 14:04
我以为你在学习,看来是小看你啦

你好!MQTT的服务器可以搭建吗?积分不够,不能直接发信息给你。我的q.q 4376-78-222.

使用特权

评论回复
37
dong_abc| | 2017-3-10 00:11 | 只看该作者
我确实打算看看go语言实现的分布式设计。

使用特权

评论回复
38
keer_zu|  楼主 | 2017-3-10 12:44 | 只看该作者
dong_abc 发表于 2017-3-10 00:11
我确实打算看看go语言实现的分布式设计。

p2p么?

使用特权

评论回复
39
renxiaolin| | 2017-3-10 16:06 | 只看该作者
chendata 发表于 2017-3-9 20:07
你好!MQTT的服务器可以搭建吗?积分不够,不能直接发信息给你。我的q.q 4376-78-222. ...

可以搭建,ubuntu下 sudo apt-get install mosquitto

使用特权

评论回复
40
ksbaaa| | 2017-3-10 20:32 | 只看该作者
膜拜一番

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则