【问题标题】:Trying to publish in messageArrived() with the Paho Client MqttCallback尝试使用 Paho 客户端 MqttCallback 在 messageArrived() 中发布
【发布时间】:2015-08-12 07:53:32
【问题描述】:

我正在尝试在messageArrived(...) 中发布对传入消息的响应。但是发布挂起和下一行:logOutgoingMessage(topic, message) 永远不会被调用...最后我遇到死锁并且客户端断开连接。

这是我的代码:

@Startup
@Singleton
public class AppliMqttClient implements MqttCallback {

@EJB
private AppliFacade facade;

@PostConstruct
public void start() {
    try {
        // connection options
        connOpts = new MqttConnectOptions();
        connOpts.setKeepAliveInterval(120);         
        connOpts.setCleanSession(true);
        connOpts.setWill(TESTAMENT_TOPIC, "DOWN!!!!!!!!!!!!!!!!!!".getBytes(), 0, false);

        client = new MqttClient(BROKER_URL, MQTT_CLIENT_ID);
        client.setCallback(this);
        connect();

        client.subscribe(SUBSCRIPTION_TOPIC, QoS);
    } catch (MqttException me) {
        log.error("Connection to " + BROKER_URL + " failed");
        logMqttException(me);
    }

}

private void connect() {
    // Tying a cycle of reconnects.
    boolean tryConnecting = true;
    while (tryConnecting) {
        try {
            client.connect(connOpts);
        } catch (Exception e1) {
            log.error("Connection attempt failed with '" + e1.getCause() + "'. Retrying.");             
        }
        if (client.isConnected()) {
            log.info("Connected to Broker " + BROKER_URL);
            tryConnecting = false;
        } else {
            pause();
        }
    }
}

private void publishAMessage(String topic, String pubMsg) {
    MqttMessage message = new MqttMessage(pubMsg.getBytes());
    message.setQos(QoS);
    // Publish the message
    log.info("Publishing to topic \"" + topic + "\" qos " + QoS);
    try {
        // Publish to the broker
        client.publish(topic, message);
        // Wait until the message has been delivered to the broker
        logOutgoingMessage(topic, message);
    } catch (Exception e) {
        log.error("Publishing to topic \"" + topic + "\" qos " + QoS + "failed.", e);
    }
}

private String handleRquest(AbstractRequest request) throws JsonProcessingException {
    ...

    return jsonResp;
}

@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
    // generate the response message ID
    messageId = "EB" + System.currentTimeMillis();

    // log the message
    logIncomingMessage(topic, message);

    // handle the message
    AbstractRequest request = getMapper().readValue(message.toString(), AbstractRequest.class);

    // handle the request
    String jsonResp = handleRquest(request);

    // publish message
    publishAMessage(request.getReplyTopic(), jsonResp);
}

/**
 * 
 * Method callback is invoked when a message published by this client is
 * successfully received by the broker.
 * 
 */
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
    // NOT NEEDED
}

}

【问题讨论】:

    标签: java mqtt paho


    【解决方案1】:

    按照以下方式更改代码。

    MqttDeliveryToken token;
    ...
    MqttTopic mqttTopic = client.getTopic(topic);
    try {
      // Publish to the broker
      token = mqttTopic.publish(new MqttMessage(pubMsg.getBytes()));
      logOutgoingMessage(topic, message);
      ...
     }
    

    但我不明白为什么第一个实现不起作用:x 可能在带有 QoS 2 的 messageArrived() 中发布不合适?

    【讨论】:

    • 我遇到了非常相似的问题,但我一直在发布 QoS=0 的消息。如果消息以 QoS 1 或 2 发布,对我来说效果很好。
    【解决方案2】:

    可以在此实现中发送新消息 回调(例如,对此消息的响应),但 实现不能断开客户端,因为它将是 无法为正在处理的消息发送确认, 就会发生死锁。

    official link from eclipse.org

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-06
      • 2017-04-22
      • 1970-01-01
      相关资源
      最近更新 更多