2016-04-07 2 views
0

Я разрабатываю интерфейс API REST, который в некоторых частях должен взаимодействовать с MQTT через клиентскую библиотеку Paho. В соответствии с проектом, Pāho клиент может использовать только один обратный вызов для каждого полученного сообщения:Рекомендации по обработке сообщений MQTT с библиотекой Java 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) { } 
} 

Я борюсь в выяснении «правильный» способ обработки принятого сообщения и реагировать соответствующим образом - как бы я написать свой обратный вызов, избегая гигантский переключатель() на некоторых частях полезной нагрузки или темы?

+0

Что такое пользовательская подписка на достаточное количество тем, что проблема с if/switch является проблемой? Вы должны сделать фильтрацию где-то – hardillb

+0

Не возражаете против темы: мои сомнения все еще присутствуют при проверке некоторых данных о полезной нагрузке, а также –

ответ

2

Короткий ответ: Большое утверждение if/switch является решением.

Если вам необходимо принимать решения на основе полезной нагрузки, вам необходимо проанализировать полезную нагрузку, неважно, что. Если вы можете фильтровать типы полезных данных на основе тем, то вы упрощаете их, передавая разбор синтаксиса для отдельных методов.

+0

Итак, похоже, мой вопрос не был таким глупым в конце концов ... Я несколько облегчен :) –

2

Вы можете избежать утверждения if/switch с помощью отправки Map.

Определить простой интерфейс (это также 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); 
} 

Это легче поддерживать при добавлении новых тем или форматы полезной нагрузки, как вам нужно всего лишь добавить строку кода вместо копаться в великана, если/иначе водопады.

То же самое относится к случаю, когда вам нужно отправлять сообщения на основе некоторого свойства полезной нагрузки. Вы обрабатываете полезную нагрузку в обратном вызове messageArrived, а затем используете карту отправки.

0

Отправка карта казалась хорошей идеей для меня, пока я не обнаружил, что вы может фактически отдельные слушатели за подписку, например:

client.subscribe(topic, new IMqttMessageListener() { 

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

}); 

Это должно помочь вам отделить ваши обработчик сообщений без некрасиво, если заявлений ,