2

我正在尝试编写一个通过 WiFi 和 MQTT 协议控制一群机器人的应用程序。我已经进行了一些测试来衡量它对于我的应用程序是否足够快。我想要一个平均不超过 25-30 毫秒的控制循环(从 PC 到机器人并返回的消息)。

我使用 Paho Java 客户端编写了一个应用程序,它在两台机器上运行。当收到关于 topic1 的消息时,它会发布到 topic2。Topic2 由第二台机器订阅,然后发布到 topic1。

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

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

当所有发布和订阅都使用 QoS 0 进行时,循环时间平均约为 12 毫秒。但是,我想使用 QoS 1 来保证发送给机器人的命令将始终到达目的地。当我测试循环时间时,它平均在 250 毫秒左右。

是什么导致时间增加这么多?据我了解,如果没有传输错误,则交换的数据包数量会随着 QoS1 翻倍(每条消息都有从代理发送到客户端的 PUBACK,请参阅http://www.hivemq.com/mqtt-essentials-part-6 -mqtt-服务质量级别/)。

我可以以某种方式减少这个时间吗?我尝试过 Mosquitto 和 Apache Apollo 代理,两者都复制了相同的结果。

编辑:

我稍微改变了一个测试程序。现在,我有两个 mqtt 客户端实例在同一台机器上运行。一是发布者,二是订阅者。发布者以 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);
    }
}

Broker(具有默认配置的 mosquitto)在同一本地网络中的另一台机器上运行。我所取得的成果比以前更加离奇。现在,一条 QoS 为 1 的消息到达订阅者大约需要 8-9 毫秒。使用 QoS 2 大约为 20 毫秒。但是,使用 QoS 0,我得到平均值。时间从 100 毫秒到甚至 250 毫秒!我猜这个错误在我的测试方法中的某个地方,但我看不到在哪里。

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 回答