IoTアプリケーションに適したプロトコルの選択


12

Thing / Constrained DeviceがGPS位置を一定の間隔で特定のサーバーに送信するIoTシナリオが機能しています。制約のあるデバイスは、バッテリー駆動で接続にGSM / SIMシールドを使用するArduinoのようなボードです。これらは私たちの設計目標です:

  • バッテリー寿命を最大化
  • データ転送を最小限に抑える

テストの目的で、HTTPを使用して約500バイトのメッセージを生成しましたが、データ転送にはより適切なプロトコルを使用する時が来ました。データ転送の特徴のいくつかは次のとおりです。

  • ペイロードは、通常、かなり小さい未満50バイト(かなり遠く離れて、典型的なのMTUから、すなわちすべてがIPパッケージに収まる必要があります)
  • データは約1分に1回送信されます。一部の差異は重要ではありません。
  • いくつかのメッセージを失うことはOK
  • 現在、デバイスはサーバーからの応答を必要としませ(ただし、将来的に変更される可能性があります)。サーバーはデバイスとの会話を開始する必要もありません

これまでのところ、これらの可能性について考えてきました。

  • TCPを介したカスタムプロトコル。これにより、HTTPヘッダーが削除され、メッセージが10分の1に小さくなります。これは私たちの信頼できる/保守的なアプローチです。
  • UDP経由のカスタムプロトコル。UDPのヘッダーは小さく、信頼性のためのオーバーヘッドがないため、かなり効率的であることが期待されます。コメントされているように、ここで1つのメッセージが失われることも、心配することもありません...しかし、私たちが認識していない非信頼性に関する他の問題がある可能性があります。
  • MQTT(TCP経由の標準):TCPと比較して既存のオーバーヘッドがほとんどないため、これもオプションとなる可能性があります...しかし、GSM / SIMテクノロジーの経験があまりなく、方法継続的なMQTT接続はこのように機能し、接続のハートビート帯域幅がこのような低頻度のデータ転送に適しているかどうかを示します。
  • CoAP(UDP 経由の標準):有望であるようです。ヘッダーとUDPを介して動作するためのオーバーヘッドはわずか4バイト。ただし、UDPの未知のリスクがあります。

誰かが何かヒントを与えることはできますか?前もって感謝します。


1
このシナリオの@RichardChambersでは、信頼性はそれほど重要ではありません。あちこちでいくつかのパッケージを失う余裕があります。Ackingは必要ありません。UDPの上で信頼性に取り組むことはあまり意味がないと思います。それがTCPの目的です。
bgusach

1
カスタムプロトコルを設計することによってホイールを再発明することはしません。CoAP対MQTTのグーグルはあなたにもっと考慮を与えるでしょう。ソリューションの将来性を保証する必要がありますか。将来、より厳しい要件に対応しますか(損失の保証、応答時間、相互運用性など)?デバイスはNATされていますか?ゲートウェイの背後にあるデバイスのグループ化はありますか?多くの未知数...
ガンビットサポート

回答:


6

TCP、UDP、およびMQTTの私の経験に関するいくつかの考え、および確認する追加のリソース。

UDPを使用すると、1つのネットワークノード(クライアント)上のアプリケーションが、送信されたUDPメッセージの一部しか表示しないというサイレント障害の問題が発生しました。ネットワークトラフィックが失敗する理由は多すぎます。UDPの問題は、パケットのプロデューサーとパケットのコンシューマーとの間のネットワークパス内のノードのいずれかが正当である場合は常に、パケットがほとんど破棄される可能性があることです。ウィキペディアのトピック「パケット損失」を参照してください。

問題は、現在のネットワークコンテキストでの損失率はどの程度かということです。したがって、これがLANまたはサブネットワーク内での通信である場合、損失率は低くなる可能性があります。WANまたはインターネット全体で、損失率は非常に高くなる可能性があります。UDPパケットはさまざまな理由で破棄されてルーティングされますが、ネットワークの状態により、そのホップカウントは減少します。説明責任のない大きな空洞にパケットを送信すると、サイレント障害の可能性が残ります。

あなたの場合は、ACKを受信せずにタイムアウト後に再送信する単純なACKで十分だと思われます。

維持されたTCP接続を介してXMLメッセージを送信しましたが、うまくいきました。完全なメッセージをそれぞれバッファーでアプリケーション層に配信して処理する層がありました。XMLを使用してメッセージをパッケージ化し、メッセージの開始用のXML開始タグと、メッセージ全体がいつ受信されたかを知るためのXML終了タグを付けました。

TCPには、パケットの順次順序、繰り返しなし、接続されたトランスポートメカニズムであることなど、いくつかの機能があります。つまり、検出に時間がかかる場合がありますが、もう一方の端が消えたかどうかがわかります。接続と切断により遅延が発生する可能性がありますが、通常の状況では厄介ではありませんが、ネットワークの状況によってTCPスループットが低下する可能性があります。

MQTTは、ネットワークトランスポート層(通常はTCP)によってトランスポートされるプロトコルです。MQTTはパブリッシュ/サブスクライブモデルを使用するため、メッセージの保存はありません。そのため、パブリッシャーがメッセージをパブリッシュするときに、サブスクライバーがその時点で接続されていない場合は、接続してもメッセージは表示されません。MQTTはほぼリアルタイムですが、それが頭字語のテレメトリ部分のすべてです。小さなメッセージにはMQTTが好きで、Mosquittoを使用してMQTTを介してJSONペイロードでいくつかの実験を行っています。この記事を参照してください。MQTTとサービス品質の概要を含む、Mosquitto(MQTT)による信頼性の高いメッセージ配信。また、サンプルアプリケーションIoT – MQTT PublishおよびSubscriber C Codeを含むリソースへのリンクを含むこの簡単な記事を参照してください。

メッセージを格納するためにサブスクライバーでJSONテキストとSQLite3データベースを使用したMQTTでの私の実験は、ソースがCであり、非常に乱雑ですが、https://github.com/RichardChambers/raspberrypi/tree/master/mqttにあります。

13分のビデオ#144インターネットプロトコル:CoAP対MQTT、ネットワークスニッフィング、IKEA Tradfri Hackingの準備を示します。これは、CoAP(Constrained Application Protocol)に関する興味深い記事です。CoAPはIoTの「最新の」プロトコルです。CoAPのこの合計があります:

アーリーアダプターは、制約付きアプリケーションプロトコルが制約付きネットワークおよびデバイスに対して非常に適切に機能することに同意します。あまり知られていないもの:「非常に輻輳したワイヤレスネットワーク-Wi-Fiまたはセルラー-MQAPなどの伝送制御プロトコルベース(TCP)プロトコルがハンドシェイクを完了できない場合でも、CoAPは引き続き機能します。 「バーミラードは言った。

これは、他のほとんどのIoTプロトコルとは異なり、CoAPはUDPに基づいて構築されているためです。つまり、TCPで発生するようなプロトコルハンドシェイクやエラー修正はありません。「CoAPはHTTPほど信頼性が高くない、またはMQTTのようなメッセージの配信を保証しない可能性がありますが、非常に高速です」とMatthieuは述べています。「一部のメッセージが受信されなくても問題ない場合は、同じ時間内にさらに多くのメッセージを送信できます。」

AMQP、STOMP、CBORなど、他にもいくつか見られるかもしれません。CBOR標準のWebサイト、およびこの論文、CBORプロトコルの実装と評価を参照してください。この記事「メッセージングプロトコルの選択:AMQP、MQTT、またはSTOMP」を参照してください。これは、AMQP、MQTT、およびSTOMPを比較対照し、最後にRabitMQブローカーに関する注記を記載しています。

うまくいけば、これは多くの人があなたのユースケースごとにそこからプロトコルスープをナビゲートし始めるのを助けることができます。企業ではさまざまなニーズを持つ多くのアプリケーションを使用することが一般的であるため、異なるアプリケーション全体で3つのブローカーすべてが必要になる可能性は確かにあります。RabbitMQのような堅固なマルチプロトコルポリグロットブローカーが登場するのは、STOMP、MQTT、またはAMQPを送信して他のブローカーの1つを取得できるためです。これらのプロトコルのいずれかでロックインする必要はありません。3つすべてがRabbitMQブローカーでサポートされているため、アプリケーション間の相互運用性にとって理想的な選択肢です。プラグインアーキテクチャにより、RabbitMQは、これらのプロトコルの追加または更新されたバージョンを将来サポートするように進化することもできます。

約60枚のスライドのこのスライド共有パッケージは、信頼性と堅牢性に対するニーズが異なる2つの異なるIoTグループ、コンシューマーとインダストリアルのニーズを検討する4つの異なるIoTプロトコルを比較対照します。IoTに適したメッセージング標準は何ですか?


4

UDPに最適なアプリケーションのように聞こえます。クライアントサーバートポロジ(pub / subは不要)、パケット損失に耐性があり、単一パケット送信間の大きなギャップは、順不同の到着が問題にならないことを意味します。

接続の確立とパケットオーバーヘッドの節約は、有利に機能します。

サイレント障害の問題を軽減する必要があるだけです。これを行う方法はたくさんありますが、私の提案は、x(例:10)パケットを受信するたびにサーバーに応答させることです。このようにして、クライアントは通過するパケットの数を認識し、それがしきい値を下回っている場合は、パケット損失に対抗するために送信頻度を上げることができます。何も問題が解決しない場合、TCPは何の役にも立たないので、状態が解消するまでクライアントを遭難モードに置くことをお勧めします。

インターネット上でのUDPパケットの損失は一般的に高くはありませんが、それが通常であれば一時的な現象です。GSMは、ある程度のバッファリングと無線信号評価を提供するため、とにかくスプリアスノイズに対してある程度の許容範囲を提供します。


4

GSM / SIMを使用するように外部から制限されていますか?

別の方法として、LoRaネットワークを使用することもできます。

  • 小さなペイロード用に高度に最適化されています
  • エネルギー使用量を最小限に抑えるように設計されている(したがって、バッテリー寿命が最大になる)
  • 設計により長距離
  • 接続クラスがある(常にオン、確認済み、未確認)
  • ダウンロードウィンドウがスケジュールされている(ファームウェアの更新やRX ACKなど)

ほとんどの国で既存のコミュニティまたは商用のLoRaインフラストラクチャに接続できます。または、より適切な場合は独自のLoRaハブを展開できます。

世界的に活発に開発されており、プロトタイピングシールド(Arduinoなど)を簡単に入手できます。


1
質問で述べたように、1分に1回は頻度が高すぎて、LoRaノードの推奨送信間隔に適合しません。
Chris Stratton、2018

1
1分はあまりにも頻繁に同意します。@bgusachはアプリケーションについて言及していませんが。ペイロードをバイナリエンコードしてサイズを削減でき、3〜5分(または10分)の間隔を使用できる場合は、理想的です。とにかく、それは以前に回答で言及されなかったと私が指摘するように、単なる提案です。
BrendanMcL 2018

1
はい、私が正しく読んでいれば、4分間隔の50バイトのようなものはほとんど適合しません。しかし、それは検証を必要とします、それは少なくとも2倍簡単にオフになる可能性があります。
クリスストラットン2018

1
興味深いですが、私たちはGSM / SIMに制約があります(これは消費者向け製品であり、インフラストラクチャがなくてもどこでも購入して使用できるものです)。
bgusach 2018

3

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を使用して、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™
適切

一方、POST(汎用動詞として)のような他の動詞は、REST APIではより一般的であるということを、アーキテクチャー側から同意します。REST APIを開発している成熟度レベルによって異なります。簡単な実装と既存のフレームワーク(クライアントおよびサーバー)との互換性の利点を維持しながら、HTTPを最小化する方法を示し、同時に人間が読みやすいようにしたかっただけです。応答サンプルで応答すると混乱を招きました...データを送信したい場合は、もちろんPOSTまたはGETメッセージを使用します-POSTの場合は、最初のサンプルで示したjsonコンテンツを使用します。
Christoph Bimminger

3

「最良の」プロトコルはありません。考慮すべき多くのトレードオフ:

  • デバイスは、ランダムなポートがブロックされたランダムなネットワーク上にありますか?その場合は、HTTPSを使用することをお勧めします。

  • UDPを送信する場合、常に最後のN回の測定を毎回送信できるため、小さなパケット損失は無視されます。また、ACKパケットを送信して、UDPを信頼できるプロトコルに変えることもできます。(UDP上のほとんどのプロトコルはこれを行います。)

  • データが暗号化されていない状態で公開されても、顧客は気にしますか?ハッカーが不正なデータを暗号化されていない接続に挿入できるかどうか、顧客は気にかけますか?(その場合、暗号化が必要になる場合があります。)

  • 誰かがあなたのプロトコルを盗聴してデータを操作するとどうなりますか?あるデバイスが別のデバイスのデータを上書きするのを防ぐことはできますか?

  • 最大でいくつのデバイスを使用しますか?これらのデバイスすべてにどのように対処しますか?データを必要な場所にどのようにルーティングしますか?サーバーインフラストラクチャのメンテナンスとアップグレードをどのように処理しますか?経験がない場合は、多くの同時接続を処理する能力を過大評価している可能性があります。ベンダーにアウトソーシングする(そしてAWS IoTなどのプロトコルを使用する)のが最善です。


3

HTTPとMQTTの伝送速度を比較する正確なテストがあります。test2を参照してください。現在のシナリオでは、MQTTはHTTPに比べてトラフィック(およびバッテリー)が50分の1になります。

MQTTとプレーンTCP(メッセージサイズ)の間に基本的に違いはありません。MQTTペイロードのプレーンTCPおよびバイナリメッセージとJSONの間に基本的に違いはないと私は言います。このように、MQTT + JSONを使用し、データの配信と表現をこの技術に依存する方がはるかに便利です。鍵の名前は多少短くするだけです。

UDPに関しては、送信が毎分1回の場合は、TCPを使用することをお勧めします。伝送が10〜20分に1回以上の場合は、UDPをより多くのトラフィック/バッテリー効果的なソリューションと見なすことができます。ACKを使用して独自のプロトコルを開発する場合は、MQTTまたはTCPを使用して、ビジネスケースに集中することをお勧めします。

一般に、実装が簡単であればあるほど、最短時間で達成できる最良の結果が得られます。私があなただったら、その場合は、UDP +独自のバイナリ形式とMQTT + JSONをテストして、それらの1つを選択する方がよいでしょう。または、MQTT + JSONから始めて、私のケースで問題ないかどうかを考えます。


1
ここで、UDPに対するいくつかの言葉を述べます。世界中の100か国以上に顧客を抱える大規模なSaaS GPSフリート管理システム(1台以上の車両が接続されている)を維持しています。そして最近、米国に拠点を置くインターネットプロバイダーが、何らかの理由でM2Mアプリケーションであっても、米国から送信されるUDPパケットをブロックしていることを発見しました。数か月前に開始されましたが、非常に苦痛なので、TCPベースのプロトコル(MQTT)を選択し、グローバル標準に依存することをお勧めします。いつか、そして一部の国では、接続を維持するためにWebSocketを介してMQTTを使用することを余儀なくされるでしょう。ちょっとしたアドバイス。
2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.