2

WiFi と MQTT プロトコルを介してロボットの群れを制御するアプリケーションを作成しようとしています。私のアプリケーションにとって十分に速いかどうかを測定するために、いくつかのテストを実行しました。平均 25 ~ 30 ミリ秒以内の制御ループ (PC からロボットへのメッセージの往復) が必要です。

2 台のマシンで実行される Paho Java クライアントを使用してアプリケーションを作成しました。topic1 でメッセージを受信すると、topic2 にパブリッシュします。Topic2 は 2 番目のマシンによってサブスクライブされ、次にトピック 1 にパブリッシュされます。

    topic1            topic1
M1---------> broker ---------> M2

    topic2            topic2
M1 <-------- broker <--------- M2

すべてのパブリッシングとサブスクライブが QoS 0 で行われた場合、ループ時間は平均で約 12 ミリ秒でした。ただし、ロボットに送信されたコマンドが常に宛先に到達することを保証するために、QoS 1 を使用したいと考えています。ループ時間をテストしたところ、平均で約 250ms でした。

時間の増加の原因は何ですか?私の理解では、送信エラーがなければ、交換されたパケット数は QoS1 で 2 倍になります (メッセージごとにブローカーからクライアントに送信される PUBACK があります。http://www.hivemq.com/mqtt-essentials-part-6 を参照してください)。 -mqtt-サービス品質レベル/ )。

この時間をどうにか短縮できないか?Mosquitto と Apache Apollo ブローカーを試しましたが、どちらも同じ結果を再現しました。

編集:

テスト手順を少し変更しました。現在、同じマシン上で実行されている mqtt クライアントの 2 つのインスタンスがあります。1 つはパブリッシャーとして、2 番目はサブスクライバーとして。パブリッシャーは、次のように 10 ミリ秒間隔で 1000 メッセージを送信します。

Client publisher = new Client(url, clientId+"pub", cleanSession, quietMode, userName, password);
Client subscriber = new Client(url, clientId+"sub", cleanSession, quietMode, userName, password);
subscriber.subscribe(pubTopic, qos);

while (counter < 1000) {
    Thread.sleep(10,0);
    String time = new Timestamp(System.currentTimeMillis()).toString();
    publisher.publish(pubTopic, qos, time.getBytes());

    counter++;
}

サブスクライバーはメッセージを待って時間を測定します:

public void messageArrived(String topic, MqttMessage message) throws MqttException {
// Called when a message arrives from the server that matches any
    // subscription made by the client

    Timestamp tRec = new Timestamp(System.currentTimeMillis());
    String timeSent = new String(message.getPayload());
    Timestamp tSent = Timestamp.valueOf(timeSent);
    long diff = tRec.getTime() - tSent.getTime();
    sum += diff;

    counter++;

    if (counter == 1000) {
        double avg = sum / 1000.0;
        System.out.println("avg time: " + avg);
    }
}

ブローカー (デフォルト構成の mosquitto) は、同じローカル ネットワーク内の別のマシンで実行されます。私が達成した結果は、以前よりもさらに奇妙です。現在、QoS 1 のメッセージがサブスクライバに到達するのに約 8 ~ 9 ミリ秒かかります。QoS 2 では約 20ms です。ただし、QoS 0 では、平均を取得します。100ms から 250ms まで!エラーはテスト メソッドのどこかにあると思いますが、どこにあるのかわかりません。

4

2 に答える 2

3

QoS 0 メッセージは永続化する必要はありません。完全にメモリ内に保持できます。

QoS 1 (および QoS 2) 配信を保証できるようにするには、メッセージを何らかの形式で永続化する必要があります。これにより、単純なネットワーク転送時間に加えて、メッセージの処理時間が追加されます。

于 2015-07-15T14:29:05.667 に答える
0

同じ結果を示す 2 つのまったく異なるブローカー実装の意味は、ack パケットで応答するのに時間がかかっているコードのクライアント側である可能性があります。

onMessage コールバックで着信メソッドのすべての処理を行っていますか? その場合、この作業はすべての MQTT プロトコル処理と同じスレッドで行われるため、応答が遅れる可能性があります。大量/高速メッセージ処理の場合、通常使用されるパターンは、onMessage コールバックのみを使用して、別のスレッドが実際に処理するために着信メッセージをキューに入れることです。

于 2015-07-15T08:08:35.023 に答える