使用Paho Java库处理MQTT消息的最佳实践

时间:2016-04-07 13:26:05

标签: java mqtt paho

我正在开发一个REST API接口,在某些部分,它必须通过Paho客户端库与MQTT交互。按照设计,Paho客户端只能对收到的每条消息进行一次回调:

mqttClient = new MqttClient(MQTT_ADDRESS, MQTT_CLIENT_ID);
mqttClient.setCallback(new MqttCallbackImpl());
...
private static class MqttCallbackImpl implements MqttCallback {

    @Override
    public void connectionLost(Throwable cause) { }

    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
        switch(topic) {
            // Endless list of cases...
        }
    }

    @Override
    public void deliveryComplete(IMqttDeliveryToken token) { }
}

我正在努力找出处理收到的消息的“正确”方式并做出相应的反应 - 我如何通过避免在有效负载的某些部分或主题上使用巨大的开关()来编写回调?

3 个答案:

答案 0 :(得分:3)

您可以使用调度Map来避免使用if / switch语句。

定义一个简单的界面(这也是functional or Single Abstract Method interface)来处理你的有效载荷

interface MqttMessageProcessor {
    void processMessage(String topic, MqttMessage message) throws Exception;
}

然后根据您的要求实现不同的具体类,并将每个主题映射到适当的实例。当消息到达时,它将被分派到正确的处理程序。

Map<String,MqttMessageProcessor> dispatchMap = new HashMap<>();
dispatchMap.put("topic1", new Payload1MessageProcessor());
dispatchMap.put("topic2", new Payload2MessageProcessor());


@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
    dispatchMap.get(topic).processMessage(topic, message);
}

如果您使用的是Java8,则可以使用Map.getOrDefault方法轻松处理需要常规处理程序的情况。

@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
    dispatchMap.getOrDefault(topic, generalMessageProcessor).processMessage(topic, message);
}

当添加新主题或有效负载格式时,这更容易维护,因为您只需添加一行代码而不是挖掘到巨大的if / else瀑布。

如果您需要根据某些有效内容属性调度消息,则同样适用。您在messageArrived回调中解析有效负载,然后使用调度映射。

答案 1 :(得分:2)

简短回答:Big if / switch语句是解决方案。

如果必须根据有效负载做出决策,则必须解析有效负载而不管是什么。如果您可以根据主题过滤有效负载类型,那么您可以通过将有效负载解析移交给单独的方法来简化操作。

答案 2 :(得分:0)

发送地图对我来说似乎是一个好主意,直​​到我发现你可以每个订阅实际上有单独的侦听器,例如:

client.subscribe(topic, new IMqttMessageListener() {

        @Override
        public void messageArrived(String topic, MqttMessage message) throws Exception {
            // do something
        }

});

这可以帮助您在没有丑陋的if语句的情况下分离您的消息处理程序。