Mqtt:服务器端的持久化消息

Mqtt:服务器端的持久化消息,mqtt,paho,Mqtt,Paho,我们决定在移动应用程序中使用mqtt协议作为聊天模块。我还想在服务器端保存主题消息。但我看到,mqtt客户机在这里是全局的,所以一种方法是我必须为所有主题订阅mqtt客户机的单个实例,并将消息保存在数据库中。但这是正确的做法吗。我只是担心而已 private void buildClient(){ log.debug("Connecting... "+CLIENT_ID); try { mqttClient = new MqttClient

我们决定在移动应用程序中使用mqtt协议作为聊天模块。我还想在服务器端保存主题消息。但我看到,mqtt客户机在这里是全局的,所以一种方法是我必须为所有主题订阅mqtt客户机的单个实例,并将消息保存在数据库中。但这是正确的做法吗。我只是担心而已

private void buildClient(){
        log.debug("Connecting... "+CLIENT_ID);
        try {
            mqttClient = new MqttClient(envConfiguration.getBrokerUrl(), CLIENT_ID);
        } catch (MqttException e) {
            log.debug("build client stopped due to "+e.getCause());
        }
        chatCallback = new ChatCallback();
        mqttClient.setCallback(chatCallback);
        mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setCleanSession(false);
    }

    @Override
    public void connect() {
        if(mqttClient == null || !mqttClient.getClientId().equals(CLIENT_ID)){
            buildClient();
        }
        boolean tryConnecting = true;
        while(tryConnecting){
            try {
                mqttClient.connect(mqttConnectOptions);
            } catch (Exception e) {
                log.debug("connection attempt failed "+ e.getCause() + " trying...");
            }
            if(mqttClient.isConnected()){
                tryConnecting = false;
            }else{
                pause();
            }
        }
    }


    @Override
    public void publish() {
        boolean publishCallCompletedErrorFree = false;
        while (!publishCallCompletedErrorFree) {
            try {
                mqttClient.publish(TOPIC, "hello".getBytes(), 1, true);
                publishCallCompletedErrorFree = true;
            } catch (Exception e) {
                log.debug("error occured while publishing "+e.getCause());
            }finally{
                pause();
            }
        }   
    }

    @Override
    public void subscribe() {
        if(mqttClient != null && mqttClient.isConnected()){
            try {
                mqttClient.subscribe(TOPIC, 2);
            } catch (MqttException e) {
                log.debug("subscribing error.."+e.getCause());
            }
        }

    }

    @Override
    public void disconnect() {
        System.out.println(this.mqttClient.isConnected());
        try {
            mqttClient.disconnect();
            log.debug("disconnected..");
        } catch (MqttException e) {
            log.debug("erro occured while disconneting.."+e.getCause());
        }
    }

解决这个问题有两种可能:

  • 编写一个MQTT客户机,使用通配符(#in MQTT)订阅所有主题
  • 根据您使用的代理实现,编写一个代理插件来完成这项工作
这里很好地描述了如何同时实现这两个选项,同时也描述了第一个选项的局限性