为物联网应用选择合适的协议

物联网 协议
2021-06-13 23:54:28

我们有一个物联网场景,其中物体/受约束设备定期将其 GPS 位置发送到给定的服务器。受限设备是类似 Arduino 的电路板,由电池供电并使用 GSM/SIM 屏蔽进行连接。这些是我们的设计目标:

  • 最大限度地延长电池寿命
  • 最小化数据传输

出于测试目的,我们使用 HTTP 生成大约 500 字节的消息,但现在是使用更合适的协议进行数据传输的时候了。数据传输的一些特征如下:

  • 所述有效载荷是非常小,通常小于50个字节少(相当远离典型的MTU,即一切应该适合在IP封装)
  • 数据应该大约每分钟发送一次一些差异并不重要。
  • 丢失一些消息可以的
  • 现在,设备不需要来自服务器r 的任何类型的响应(但是,这在未来可能会改变)。服务器也不必开始与设备的任何对话

到目前为止,我们已经想到了这些可能性:

  • TCP 上的自定义协议这将消除使消息小 10 倍的 HTTP 标头。这是我们可靠/保守的方法。
  • UDP 上的自定义协议由于 UDP 具有较小的标头并且没有可靠性开销,因此我们期望非常高效。正如所评论的,在这里丢失一条消息或没有问题都没有关系……但是,可能存在我们不知道的其他不可靠性问题。
  • MQTT(基于 TCP 的标准):与 TCP 相比几乎没有现有开销,这也可以是一种选择……但是,我们对 GSM/SIM 技术没有太多经验,也不知道如何一个连续的 MQTT 连接会以这种方式工作,以及连接心跳带宽是否值得用于这种低频数据传输。
  • CoAP(UDP 上的标准):似乎也很有希望。标头和通过 UDP 工作的开销仅为 4 个字节。然而,存在 UDP 的未知风险。

任何人都可以提供任何提示吗?提前致谢。

4个回答

关于我在 TCP、UDP 和 MQTT 方面的经验的一些想法以及一些要审查的其他资源。

使用 UDP 我遇到了静默故障问题,其中一个网络节点(客户端)上的应用程序只能看到一些已发送的 UDP 消息。网络流量可能出错的原因太多了。UDP 的问题在于,只要数据包的生产者和数据包的消费者之间的网络路径中的任何节点允许,几乎都可以丢弃数据包。请参阅维基百科主题数据包丢失

问题是无论当前网络环境如何,您的丢失率是多少。因此,如果这是 LAN 或子网内的通信,您的丢失率可能很低。在 WAN 或 Internet 上,您的丢失率可能很高。UDP 数据包由于多种原因被丢弃并进行路由,但是网络条件允许该跳数递减。在没有问责制的情况下将数据包发送到巨大的空隙中,可能会导致静默失败。

在您的情况下,听起来只是一个简单的 ack,在超时后重新传输而没有收到 ack 就足够了。

我已经通过维护的 TCP 连接完成了 XML 消息,并且效果很好。我有一个层将缓冲区中的每个消息都传递给应用程序层来处理。我使用 XML 来打包消息,其中包含用于消息开头的 XML 起始标记和用于了解何时收到整条消息的 XML 结束标记。

TCP 确实具有一些特性,例如数据包的顺序顺序、无重复,并且作为一种连接的传输机制意味着您知道另一端是否消失,尽管可能需要一段时间才能找到。尽管网络条件会导致 TCP 吞吐量变慢,但在普通条件下连接和断开连接会引入延迟但不会造成负担。

MQTT 是一种由网络传输层(通常为 TCP)传输的协议。MQTT 使用发布/订阅模型,因此没有消息存储。因此,当发布者发布消息时,如果订阅者当时未连接,那么当它连接时,它将看不到该消息。MQTT 几乎是实时的,我想这就是首字母缩略词的遥测部分的全部内容。我确实喜欢用于小消息的 MQTT,并且一直在使用 Mosquitto 通过 MQTT 对 JSON 有效负载进行一些实验。请参阅这篇文章使用 Mosquitto (MQTT)进行可靠的消息传递,其中包含 MQTT 和服务质量的概述。并查看这篇包含资源链接的简短文章,包括示例应用IoT – MQTT 发布和订阅者 C 代码

我使用 JSON 文本和订阅者中的 SQLite3 数据库来存储消息的 MQTT 实验位于https://github.com/RichardChambers/raspberrypi/tree/master/mqtt尽管源代码是 C 语言并且非常混乱。

这是一个 13 分钟的视频#144 互联网协议:CoAP 与 MQTT、网络嗅探和准备宜家 Tradfri 黑客这是一篇关于 CoAP 的有趣文章,受限应用协议:CoAP 是物联网的“现代”协议CoAP 的总结如下:

早期采用者一致认为,受限应用协议非常适用于受限网络和设备。一些不太为人所知的事情:“在非常拥挤的无线网络(Wi-Fi 或蜂窝网络)上,CoAP 可以继续工作,而基于传输控制协议 (TCP) 的协议(如 MQTT)甚至无法完成握手, ”弗米拉德说。

这是因为与大多数其他物联网协议不同,CoAP 建立在 UDP 之上。换句话说,这意味着没有 TCP 遇到的协议握手或纠错。“CoAP 可能不像 HTTP 那样可靠,也不像 MQTT 那样保证消息的传递,但它非常快,”Matthieu 指出。“如果您对某些未收到的消息感到满意,您可以在同一时间范围内发送更多消息。”

还有一些其他的,例如 AMQP、STOMP 和 CBOR,您也可以看看。参见CBOR标准网站以及本论文,CBOR协议的实施和评估请参阅这篇文章,选择您的消息传递协议:AMQP、MQTT 或 STOMP,其中比较和对比了 AMQP、MQTT 和 STOMP,并以关于 RabitMQ 代理的注释结尾:

希望这可以帮助许多人开始为您的每个用例导航协议汤。由于公司拥有许多具有不同需求的应用程序是很常见的,因此您当然可能需要跨不同应用程序的所有三个代理。这就是像 RabbitMQ 这样可靠的多协议、多语言代理的用武之地——因为它可以将 STOMP、MQTT 或 AMQP 发送进来,然后将其中一个发送出去。您不需要被这些协议中的任何一个锁定——RabbitMQ 代理都支持这三种协议,使其成为应用程序之间互操作性的理想选择。插件架构还使 RabbitMQ 能够在未来发展以支持这些协议的附加或更新版本。

这个包含约 60 张幻灯片的幻灯片共享包对四种不同的 IoT 协议进行了比较和对比,着眼于两个不同的 IoT 组(消费者和工业)的需求,它们对可靠性和稳健性有不同的需求。物联网的正确消息传递标准是什么?.

听起来像是 UDP 的完美应用:客户端-服务器拓扑结构(不需要发布/订阅),可以容忍数据包丢失和单个数据包传输之间的大间隙,这意味着无序到达不是问题。

连接建立和数据包开销的节省将对您有利。

您只需要缓解静默故障问题。有很多方法可以做到这一点,但我的建议是让服务器在每次收到 x(例如 10 个)数据包时做出响应。这样客户端就知道有多少数据包通过,如果它低于阈值,它可以提高传输频率以抵消数据包丢失。如果没有任何事情通过,那么 TCP 无论如何也不会提供帮助,因此您最好将客户端置于遇险模式,直到情况消失。

Internet 上的 UDP 数据包丢失一般不高,如果是,则通常是暂时现象。GSM 提供了一些缓冲和无线电信号评估,因此无论如何都能对杂散噪声提供一定的容忍度。

您是否受到外部限制以使用 GSM/SIM?

另一种选择是使用 LoRa 网络,该网络:

  • 针对小负载高度优化
  • 设计用于最小的能源使用(因此最大的电池寿命)
  • 远距离设计
  • 具有连接类(始终开启、已确认、未确认)
  • 有预定的下载窗口(例如,用于固件更新或 RX ACK)

您可以插入大多数国家/地区的现有社区或商业 LoRa 基础设施,或者如果更合适,您可以部署自己的 LoRa 集线器。

全球范围内都有积极的开发,并且很容易获得原型开发板(例如 Arduino)。

我更喜欢带有 JSON 数据的最小 HTTP 响应...... HTTP 响应可以远低于 500 字节的 HTTP 传输,并且您仍然与 RESTful Web 应用程序的许多客户端兼容。

具有大约 130 字节 HTTP 数据的最小 HTTP 消息(例如,带有 JSON 结果)如下所示:

HTTP/1.1 200 OK
Server: ProprietaryAndroid
Connection: close
Content-Type: application/json
{
  "lat": "42.00000",
  "long": "10.00000"
}

如果您只想将数据从您的应用程序发送到服务器,您可以简单地使用 HTTP GET,您可以在其中将经纬度设置为 URL 参数。请求的数据甚至少于响应的数据。

GET /?lat=42.00000&long=10.0000 HTTP/1.1
Host: 192.168.0.2 
User-Agent: Proprietary
Accept: */* 
Connection: close