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


12

我们正在工作一个IoT场景,其中Thing / Constrained设备定期将其GPS位置发送到给定服务器。受限设备是一块类似于Arduino的板,该板由电池供电,并使用GSM / SIM屏蔽罩进行连接。这些是我们的设计目标:

  • 延长电池寿命
  • 最小化数据传输

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

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

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

  • TCP上的自定义协议。这将摆脱HTTP标头,使消息小10倍。这是我们可靠/保守的方法。
  • UDP上的自定义协议。由于UDP的标头较小,并且没有开销,因此我们希望它非常有效。如所评论的,在此处丢失一条消息或无需担心……但是,可能还有其他我们不了解的不可靠性问题。
  • MQTT(TCP上的标准):与TCP相比,几乎没有任何开销,因此这也是一种选择...但是,我们在GSM / SIM技术方面经验不足,也不知道如何连续的MQTT连接将以这种方式工作,并且连接心跳带宽对于这种低频数据传输是否值得。
  • CoAP(UDP上的标准):看起来也很有希望。标头和UDP工作仅4字节开销。但是,存在未知的UDP风险。

有人可以给任何提示吗?提前致谢。


1
在这种情况下@RichardChambers,可靠性不是那么重要。我们有能力在这里或那里丢失一些包裹。Ack不需要。我认为在UDP之上进行可靠性工作没有太大意义,这就是TCP的目的。
bgusach

1
我不会通过设计自定义协议来重新发明轮子。CoAP与MQTT的比较会给您带来更多考虑。您是否需要对解决方案进行过时的验证,即 将来处理更严格的要求(损失保证,响应时间,互操作性等)?设备是否经过NAT?网关后面是否有设备分组?许多未知数...
Gambit支持

Answers:


6

关于我在TCP,UDP和MQTT方面的经验的几点思考,以及一些需要复查的其他资源。

使用UDP,我遇到了静默故障问题,其中一个网络节点(客户端)上的应用程序仅看到已发送的某些UDP消息。网络流量可能出问题的原因太多。UDP的问题在于,只要数据包生产者与数据包使用者之间的网络路径中的任何节点都可以保证,就可以丢弃很多数据包。请参阅Wikipedia主题数据包丢失

问题是,在当前网络环境下,您的损失率是多少?因此,如果这是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,网络嗅探以及为IKEA Tradfri Hacking做准备。这是一篇关于CoAP(受约束的应用协议)的有趣文章:CoAP是物联网的“现代”协议。CoAP的摘要如下:

早期采用者一致认为,受约束的应用协议对于受约束的网络和设备非常有效。不太为人所知的是:“在非常拥挤的无线网络(Wi-Fi或蜂窝网络)上,CoAP可以继续工作,而基于MQTT的基于传输控制协议(TCP)的协议甚至都无法完成握手, ” Vermillard说。

这是因为与大多数其他IoT协议不同,CoAP是基于UDP构建的。换句话说,这意味着没有TCP遇到的协议握手或纠错。Matthieu指出:“ CoAP可能不像HTTP那样可靠,或者不能保证像MQTT这样的消息传递,但是它非常快。” “如果您还可以接收一些消息,那么您可以在同一时间范围内发送更多消息。”

您可能还会看到其他一些内容,例如AMQP,STOMP和CBOR。请参阅CBOR标准网站以及本论文,CBOR协议的实现和评估。请参阅本文,选择消息传递协议:AMQP,MQTT或STOMP,它比较并对比了AMQP,MQTT和STOMP,并以关于RabitMQ代理的注释结尾:

希望这可以帮助许多人开始针对每个用例浏览协议汤。由于公司通常有许多具有不同需求的应用程序,因此肯定有可能需要跨不同应用程序的所有三个经纪人。这就是可靠的多协议,多语言经纪人(如RabbitMQ)进入的地方,因为它可以发送STOMP,MQTT或AMQP并取出其中一个。您不需要被这些协议之一所锁定-RabbitMQ代理支持所有这三个协议,使其成为应用程序之间互操作性的理想选择。该插件体系结构还使RabbitMQ能够发展为将来支持这些协议的其他版本或更新版本。

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


4

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

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

您只需要减轻静默故障问题即可。有很多方法可以做到这一点,但是我的建议是让服务器在每次接收到x(例如10)个数据包时做出响应。这样,客户端就知道有多少个数据包正在通过,并且如果它低于阈值,则可以提高传输频率以抵消丢失的数据包。如果什么都没有通过,那么TCP仍然无济于事,所以最好将客户端置于遇险模式,直到情况消除。

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


4

您是否在外部受到限制才能使用GSM / SIM?

一种替代方法是使用LoRa网络,该网络包括:

  • 针对小型有效载荷进行了高度优化
  • 设计用于最低能耗(因此可延长电池寿命)
  • 设计范围广
  • 具有连接类(始终打开,已确认,未确认)
  • 具有预定的下载窗口(例如,用于固件更新或RX ACK)

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

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


1
问题中提到的每分钟一次太频繁了,无法满足建议的LoRa节点传输间隔。
克里斯·斯特拉顿

1
同意1分钟太频繁了。尽管@bgusach没有提及该应用程序。如果可以对有效负载进行二进制编码以减小大小,并且可以使用3-5分钟(甚至10分钟)的间隔,那么它可能是理想的选择。无论如何,只是一个建议,正如我注意到的那样,答案中没有提到过。
BrendanMcL

1
是的,如果我没看错的话,大概每四分钟间隔50个字节就不太合适了。但这需要验证,很容易至少减少两倍。
克里斯·斯特拉顿

1
有趣,但是我们受到GSM / SIM的限制(这旨在成为一种消费品,可以在没有电话网络的任何基础设施的任何地方购买和使用)。
bgusach

3

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

带有aprox 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来设置lat / long作为URL参数。该请求的数据甚至少于响应。

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

7
感谢您的回答,但是HTTP响应我看不到您的意思。我们要摆脱整个HTTP协议,以节省数据传输。最重要的是,要做的GET就是使用修改资源Wrong Thing™
bgusach

从Architectutal方面同意您的观点,其他动词(如POST)(作为通用动词)同时在REST API中更常见。取决于您要开发REST API的成熟度级别。只是想展示如何最小化HTTP,同时保持简单的实现和与现有框架(客户端和服务器)的兼容性的优势,并同时保持人类可读性。用响应样本进行回答令人困惑...如果您想发送数据,那么您当然会使用POST或GET消息-如果是POST,请使用我在第一个样本中显示的json内容。
克里斯多夫·比明格

3

没有“最佳”协议。需要考虑很多折衷:

  • 您的设备是否会在随机网络中被随机端口阻塞?如果是这样,最好使用HTTPS。

  • 如果发送UDP,则始终可以每次都发送最后N次测量,因此可以忽略小的数据包丢失。您还可以发送ACK数据包,从而将UDP转换为可靠的协议。(大多数基于UDP的协议都可以这样做。)

  • 您的客户是否会关心他们的数据是否未加密地公开?您的客户是否会担心黑客是否可以将不良数据注入到那些未加密的连接中?(如果是这样,则可能需要加密。)

  • 如果有人嗅探您的协议并操纵数据该怎么办?您可以防止一台设备覆盖另一台设备的数据吗?

  • 您将拥有最大数量的设备?您将如何处理所有这些设备?您如何将数据路由到需要去的地方?您如何处理服务器基础架构的维护和升级?如果您没有经验,则可能是高估了处理许多同时连接的能力。最好外包给供应商(并使用他们的协议,例如AWS IoT)。


3

我们已经比较了HTTP和MQTT的传输速率进行了精确的测试,请参阅test2,在您当前的情况下,MQTT将为您带来比HTTP 少50倍的流量(和电池)。

MQTT和普通TCP(消息大小)之间基本上没有区别。我什至会说,MQTT有效负载中的纯TCP和二进制消息与JSON之间基本上没有区别。这样,使用MQTT + JSON并依靠此技术进行数据传递和表示要方便得多。只需将您的密钥命名为简短的名称即可。

关于UDP,如果每分钟传输一次,则最好使用TCP。如果传输是每10-20分钟或更长时间一次,则您可以将UDP视为更有效的通信/电池解决方案。如果您尝试使用ACK开发自己的协议,我建议您使用MQTT或TCP并专注于您的业务案例。

通常,实施起来越简单,您就能在最短的时间内获得最好的结果。如果我是您,那么在那种情况下,我最好测试UDP +自己的二进制格式和MQTT + JSON,然后选择其中之一。甚至只是从MQTT + JSON开始,然后考虑我的情况是否可以。


1
我将在这里提及针对UDP的几句话。我们维护着大型SaaS GPS车队管理系统(连接了超过100万辆汽车),在全球100多个国家拥有客户。最近,我们发现位于美国的互联网提供商出于某些原因(甚至对于M2M应用程序)也阻止UDP数据包从美国流出。它开始于几个月前,但是非常痛苦,因此我建议您选择基于TCP的协议(MQTT)并依赖于全球标准。有朝一日,在某些国家,您甚至将被迫在Websocket上使用MQTT来维持连接。只是很小的建议。
SHAL
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.