繁体   English   中英

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

[英]Best practices in handling MQTT messages with Paho Java library

我正在开发一个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) { }
}

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

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

定义一个简单的接口(这也是一个函数或Single Abstract Method接口 )来处理您的有效负载

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回调中的有效负载,然后使用调度映射。

简短的答案:大的if / switch语句是解决方案。

如果必须基于有效负载进行决策,则无论如何都必须解析有效负载。 如果您可以根据主题过滤有效负载类型,则可以通过将有效负载解析传递给单独的方法来简化操作。

在我发现每个订阅实际上可以有单独的侦听器之前,调度映射对我来说似乎是个好主意,例如:

client.subscribe(topic, new IMqttMessageListener() {

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

});

这应该可以帮助您在不使用难看的if语句的情况下分隔消息处理程序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM