13

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

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

メッセージを識別する他の方法があるかどうかはよくわかりませんか?可能な限り規格に準拠したいと思います。

4

2 に答える 2

23

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

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

別の見方をすれば、メッセージの送信速度が原因であろうと、メッセージの処理方法の設計によるものであろうと、クライアントが一度に1つのメッセージしか送信しなかった場合にどのように機能するかを検討することです。この場合、重複する可能性は決してないため、メッセージごとにメッセージIDを1に設定しておくことができます。

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

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

「すべてのMQTTブローカーが最後のQoS1/2メッセージのみを配信する傾向があることに気づきました」というコメントに答える:

ブローカーは、知っているクライアントにのみメッセージを送信します。初めて接続する場合、保持されたメッセージという1つの例外を除いて、過去のメッセージを取得する方法はありません。メッセージが保持されるように設定されている場合、それは「最後の既知の正常な」値です。新しいクライアントがサブスクライブすると、保持されたメッセージがすぐに送信されるため、更新頻度の低いものに役立ちます。これがあなたが言及していることだと思います。クライアントが接続されていないときにメッセージをキューに入れたい場合は、「クリーンセッション」オプションを無効にして接続し、クライアントを永続化する必要があります。また、QoS>0サブスクリプションおよびQoS>0パブリケーションを使用する必要があります。クライアントが再接続すると(クリーンセッションが無効に設定されたまま)、キューに入れられたメッセージが配信されます。通常、ブローカーでこの方法でキューに入れるメッセージの数を構成できます。これ以降のメッセージは破棄されます。重要な点は、以前に接続したことがないクライアントのキューイングメッセージは設計上サポートされていないということです。

于 2012-06-20T16:15:34.593 に答える
0

QOS1またはQOS2でより多くのメッセージを配信するには、永続メモリの概念を使用する必要があります。これでは、サブスクライバーが利用できない場合、メッセージは永続メモリに保存され、サブスクライバーが接続されると配信されます。これは、mosquitto.confファイルを構成した後もQOS0で実行できます。

于 2016-03-05T11:04:38.797 に答える