2012-06-20 23 views
9

私が働いている会社はMQTTを評価し、大規模システムのコア・メッセージング・プラットフォームとして使用することに決めました。主な理由は、プロトコルがどれほどコンパクトであり、どれほど簡単に実装できるかです。 MQTTに関する問題が1つあり、次の質問に対する答えを求めています。MQTT messageId実用的な実装

QoS1およびQoS2メッセージには、クライアントからの確認が必要です。 PUBACK、PUBREC、PUBREL、PUBCOMPを受け取ったときに私が(それを識別する)メッセージについて知っているのは、messageIdとclientIdだけです。メッセージIDは符号なしint16なので、最大値は65535です。長時間実行しているクライアント、たとえば1年に15分間、15個のQoS2メッセージを送信するのに十分な大きさはありません。

メッセージを識別する他の方法があるかどうかはわかりませんが、できるだけ標準に準拠したいと思っています。

答えて

19

おそらく最初に明らかになるのは、メッセージIDがクライアントごとと方向ごとに処理されることです。つまり、ブローカは、接続されている各クライアントに対してQoS> 0の送信メッセージごとにメッセージIDを作成し、これらのメッセージIDは他のクライアントに発行された同じメッセージに使用されている他のメッセージIDとは完全に独立しています。同様に、各クライアントは、送信するメッセージの独自のメッセージIDを生成します。

メッセージIDは一意である必要はありません。したがって、QoSレベル2の1時間あたり15メッセージを送信するクライアントは、ある時点でオーバーフローします。実際の制限は、一度に(すなわち、メッセージハンドシェイクの途中で)「飛行中」の方向に最大65535メッセージしか存在しないことである。 IDを持つメッセージが完全に処理されると、そのメッセージIDを再利用することができます。

別の方法として、メッセージが送信されているかどうかにかかわらず、メッセージが処理される方法でクライアントが一度に1つのメッセージしか受信しなかった場合、どのように動作するかを検討することです。この場合、メッセージが重複する可能性はないため、メッセージごとにメッセージIDを1に設定することができます。

複数のメッセージを一度に飛行することをサポートしたい場合は、新しいメッセージIDを割り当てる前にメッセージIDの重複がないことを確認するのが比較的簡単です。

メッセージIDはクライアントごとであるため、> 65535個のクライアントに1つのメッセージを送信すると、メッセージIDが衝突することはありません。一度に> 65535を超えるメッセージを各クライアントに送信すると、メッセージフローが完了しない場合、問題が発生します。ブローカーはそれだけが知っているクライアントにメッセージを送信します

:コメントに答える

は、「私はすべてのMQTTブローカが最後QoS1/2メッセージを配信する傾向があることに気づきました」。初めて接続した場合、1つの例外を除いて、過去のメッセージを取得する方法はありません。メッセージが保持されるように設定されている場合、それは「最後にわかった良い」値です。新しいクライアントが購読すると、すぐに保持されたメッセージが送信され、頻繁に更新されないものに役立ちます。私はこれがあなたが指しているものだと思う。接続されていないときにメッセージがキューに入れられるようにするには、クライアントを永続化するために「クリーンセッション」オプションを無効にして接続する必要があります。 QoS> 0サブスクリプションとQoS> 0パブリケーションも使用する必要があります。クライアントが再接続すると(クリーンセッションがまだ無効に設定されている状態で)、キューに入れられたメッセージが配信されます。通常、ブローカでこのようにキューに入れるメッセージの数を構成できます。ブローカでは、それ以上のメッセージは破棄されます。重要な点は、以前に接続していないクライアントのメッセージをキューに入れることは、設計上サポートされていないことです。

+0

この点をご理解いただき、ありがとうございます。 私は、すべてのMQTTブローカーが最後のQoS1/2メッセージのみを配信する傾向があることに気付きました。もっと納品したい場合はどうすればいいですか? 65535以上は何ですか?私はこれが非常に起こりそうでないことを理解していますが、可能です。 提案した解決策は、既知の受信者数に適しています。私が扱っている状況は、そこにいる受取人の数がどれくらいで、まだ工場にいるのかわからないということです。基本的にはそこにいるかもしれないが、決して入ってこないかもしれません。そして何千人もの人々がいるかもしれません。 – radekg

+0

私が明確にしていない点の1つは、メッセージIDがクライアントごとと方向ごとにあることです。私はそれを含める答えを更新しました。 – ralight

+0

私はあなたのもう一つの点にも答えました。それでも問題が解決しない場合は、別のコメントを残してください。 – ralight

0

QOS1またはQOS2でさらにメッセージを配信するには、持続性メモリの概念を使用する必要があります。これで加入者が利用できなくなったときに、メッセージは永続メモリに格納され、加入者が接続されると配信されます。これは、mosquitto.confファイルを設定した後でも、QOS0で行うことができます。