おそらく最初に明らかになるのは、メッセージ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パブリケーションも使用する必要があります。クライアントが再接続すると(クリーンセッションがまだ無効に設定されている状態で)、キューに入れられたメッセージが配信されます。通常、ブローカでこのようにキューに入れるメッセージの数を構成できます。ブローカでは、それ以上のメッセージは破棄されます。重要な点は、以前に接続していないクライアントのメッセージをキューに入れることは、設計上サポートされていないことです。
この点をご理解いただき、ありがとうございます。 私は、すべてのMQTTブローカーが最後のQoS1/2メッセージのみを配信する傾向があることに気付きました。もっと納品したい場合はどうすればいいですか? 65535以上は何ですか?私はこれが非常に起こりそうでないことを理解していますが、可能です。 提案した解決策は、既知の受信者数に適しています。私が扱っている状況は、そこにいる受取人の数がどれくらいで、まだ工場にいるのかわからないということです。基本的にはそこにいるかもしれないが、決して入ってこないかもしれません。そして何千人もの人々がいるかもしれません。 – radekg
私が明確にしていない点の1つは、メッセージIDがクライアントごとと方向ごとにあることです。私はそれを含める答えを更新しました。 – ralight
私はあなたのもう一つの点にも答えました。それでも問題が解決しない場合は、別のコメントを残してください。 – ralight