淡然逝去 2023-07-28 19:14 采纳率: 33.3%
浏览 17
已结题

MQTT怎么处理重复订阅?

MQTT里避免重复订阅时用到的字段sessionPresent,为什么我测试的 sessionPresent 全是 false,(cleanSession=false)

MqttClient client = new MqttClient("tcp://localhost:1883", "push");
            MqttConnectOptions options = new MqttConnectOptions();
            options.setUserName("aaaaaa");
            options.setPassword("aaaaa".toCharArray());
            options.setCleanSession(false);
            IMqttToken iMqttToken = client.connectWithResult(options);
            iMqttToken.waitForCompletion();
            boolean sessionPresent = iMqttToken.getSessionPresent();
            System.out.println("firstResult: " + sessionPresent);  //  第一次访问返回false  正常
            MqttMessage message = new MqttMessage();
            client.publish("tt", "zxzx".getBytes(), 1, false);
            client.disconnect();

            IMqttToken secondToken = client.connectWithResult(options);
            secondToken.waitForCompletion();
            boolean secondResult = secondToken.getSessionPresent();
            System.out.println("secondResult: " + secondResult); // 第二次不是应该返回 true 了吗?为什么还是false

  • 写回答

1条回答 默认 最新

  • 黄以礼 2023-07-28 19:17
    关注

    在MQTT协议中,sessionPresent字段指示的是客户端与服务器之间是否存在会话。当cleanSession设置为false时,表示不删除现有的会话状态,因此在客户端断开连接后再次连接时,会话仍然存在。
    然而,sessionPresent字段并不总是能够反映出会话的真实状态。具体取决于MQTT服务器的实现方式,有些服务器可能在客户端断开连接后立即删除会话,即使cleanSession设置为false。
    在你的代码中,第一次连接后打印的sessionPresent为false可能是由于服务器在客户端断开连接后立即删除了会话。因此,即使你在第二次连接时使用了相同的的选择器,服务器可能并没有保留会话状态,导致sessionPresent仍然为false。
    为了确保在第二次连接时能够正确地获取会话状态,你可以尝试在第一次连接后等待一段时间,然后再断开连接,以确保服务器的会话状态不会立即被删除。另外,你还可以检查服务器的日志或文档,以了解其会话管理的具体实现方式,以便更好地控制会话的状态。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 8月15日
  • 修改了问题 7月28日
  • 修改了问题 7月28日
  • 创建了问题 7月28日