关于 MQTT 中客户端-服务器连接建立的困惑

物联网 MQTT
2021-06-11 22:56:18

根据规范,应始终由客户端建立与服务器的连接。

客户:

使用 MQTT 的程序或设备。客户端总是建立到服务器的网络连接它可以

  • 发布其他客户端可能感兴趣的应用消息。

  • 订阅请求它有兴趣接收的应用程序消息。

  • 取消订阅以删除对应用程序消息的请求。

  • 断开与服务器的连接。

如果这个客户端订阅了一个应用程序消息,那么服务器应该将这些消息转发给这个特定的客户端。

服务器:

在发布应用程序消息的客户端和进行订阅的客户端之间充当中介的程序或设备。服务器

  • 接受来自客户端的网络连接。

  • 接受客户端发布的应用程序消息。

  • 处理来自客户端的订阅和取消订阅请求。

  • 转发与客户端订阅匹配的应用程序消息

这是否意味着如果客户端订阅了,那么即使在大多数时间没有数据流,它也会在订阅有效期间保持与服务器的连接?

我得出这个结论是因为如果客户端在订阅后断开连接,那么服务器无法将消息转发给它,因为应该建立连接的是客户端。但它不知道何时重新建立它。

3个回答

这是否意味着如果客户端订阅了,那么即使大多数时间没有数据流,它也会在订阅有效期间保持与服务器的连接?

是的,一旦建立连接,客户端将等待消息,但是它也会根据 keepalive 值定期向服务器发送 PING 消息。如果服务器未收到 PING 消息,则它可能会断开您的连接。

如果客户端在订阅后断开连接,则服务器无法向它转发消息,因为应该建立连接的是客户端。

如果客户端断开连接,那么是的,它不会接收消息,但是 MQTT 中有一些功能可以解决这个问题。

如果客户端连接到服务器时将“Clean session”标志设置为 false,则服务器将记住该客户端 ID 的订阅。一旦客户端重新连接,它就不需要重新订阅,因为服务器会记住它。

此外,您可以使用 QoS 级别 1 或 2 进行订阅。使用这些 QoS 级别,服务器将存储消息并等待客户端重新连接,然后再发送它们。这样,即使客户端断开连接并重新连接,它们仍会收到所有已发布的消息。

这个站点有一些很好的资源来解释 MQTT 协议。

这是否意味着如果客户端订阅了,那么即使大多数时间没有数据流,它也会在订阅有效期间保持与服务器的连接?

是的,您的客户端将等待消息。

...如果客户端在订阅后断开连接,则服务器无法转发消息

您必须管理断开连接(尤其是在电池供电的设备中)。这可以使用MQTT的“最后遗嘱”功能来完成:当设备断开连接时,它将发送最后一条消息。

您应该区分连接和会话。

一切都由会话定义。当 MQTT 连接第一次被授权给 broker 时,broker 会为这个连接创建 session,通常基于 client-id 连接参数。

在 MQTT 3.1.1 协议(当前在大多数客户端/代理中默认)中,您可以在连接期间指定 clean=true 或 clean=false 标志。如果 clean=true 那么代理将自动创建新会话并在连接中断/关闭时关闭它。如果 clean=false,即使客户端断开连接,broker 也会维护会话并将事件传递到那里(到某种会话存储中)。这取决于代理实现是否允许 clean=false 会话以及此类会话的最大 ttl 是多少。

在 MQTT 5.0 协议中(非常新鲜,但有远见),可以从客户端指定会话 ttl,甚至可以在建立连接后更改它。这对于不稳定的 WAN 连接(主要是物联网)或您描述的有状态连接非常有用。

从客户端的角度AFAIK目前MQTT 5.0协议可以在python被用于与gmqtt和在与JavaScript mqtt.js