Я использую Really Small Message Broker (RSMB) 1.3.0.2 с поддержкой MQTT-SN. У меня есть клиент Arduino, который разговаривает с ним по протоколу MQTT-SN.
Arduino - это спящий клиент - устройство с батарейным питанием. Вот как это работает:
- после запуска подключается к брокеру
- для каждого значения датчика он регистрирует тему и публикует первое измерение в QOS 1 (в этом примере есть 3 значения датчика) 2.1 каждый регистр и сообщение публикации подтверждаются брокером
- отключается от брокера с продолжительностью - указывая, что он просто переходит в спящий режим
- после пробуждения он снова подключается к чистому сеансу 0 (или false)
- публикует одно значение датчика в QOS 1
- ждет опубликовать подтверждение от брокера - проблема не приходит.
Проблема в том, что сообщение, отправленное на шаге 5, не подтверждается брокером. Arduino пытается повторно отправить это сообщение несколько раз, но не отвечает.
Насколько я понимаю, после повторного подключения с cleansession 0 все предыдущие подписки действительны, а также topicID для сопоставления имен тем.
Вот журнал RSBM с моими комментариями:
Client connects
20150227 152211.587 132 127.0.0.1:55701 <- MQTT-S CONNECT cleansession: 0
20150227 152211.587 1998536376 127.0.0.1:55701 XinoRf_1 -> MQTT-S CONNACK returncode 0 (0)
20150227 152211.588 CWNAN0000I Client connected to udp port 1885 from XinoRf_1 (127.0.0.1:55701)
Here start 1st topic registration and acknowledgment - its id is 1
20150227 152211.678 132 127.0.0.1:55701 XinoRf_1 <- MQTT-S REGISTER msgid: 1 topicid: 0 topicname: net/mf/ha/
20150227 152211.678 132 127.0.0.1:55701 XinoRf_1 -> MQTT-S REGACK msgid: 1 topicid: 1 returncode: 0 (0)
Here starts send and acknowledge of a 1st message in topic 1
20150227 152211.753 132 127.0.0.1:55701 XinoRf_1 <- MQTT-S PUBLISH msgid: 2 qos: 1 retained: 0
20150227 152211.753 1998536376 127.0.0.1:55701 XinoRf_1 -> MQTT-S PUBACK msgid: 2 (0)
Here start 2nd topic registration and acknowledgment - its id is 2
20150227 152211.753 132 127.0.0.1:55701 XinoRf_1 <- MQTT-S REGISTER msgid: 3 topicid: 0 topicname: net/mf/ha/
20150227 152211.846 132 127.0.0.1:55701 XinoRf_1 -> MQTT-S REGACK msgid: 3 topicid: 2 returncode: 0 (0)
Here starts send and acknowledge of a 1st message in topic 2
20150227 152211.921 132 127.0.0.1:55701 XinoRf_1 <- MQTT-S PUBLISH msgid: 4 qos: 1 retained: 0
20150227 152211.921 1998536376 127.0.0.1:55701 XinoRf_1 -> MQTT-S PUBACK msgid: 4 (0)
Here start 3rd topic registration and acknowledgment - its id is 3
20150227 152212.005 132 127.0.0.1:55701 XinoRf_1 <- MQTT-S REGISTER msgid: 5 topicid: 0 topicname: net/mf/ha/
20150227 152212.005 132 127.0.0.1:55701 XinoRf_1 -> MQTT-S REGACK msgid: 5 topicid: 3 returncode: 0 (0)
Here starts send and acknowledge of a 1st message in topic 3
20150227 152212.080 132 127.0.0.1:55701 XinoRf_1 <- MQTT-S PUBLISH msgid: 6 qos: 1 retained: 0
20150227 152212.080 1998536376 127.0.0.1:55701 XinoRf_1 -> MQTT-S PUBACK msgid: 6 (0)
Here Arduino sends disconnect request with duration 4000 (it does not matter what value is sent here, behaviour is same)
20150227 152212.080 1998536376 127.0.0.1:55701 XinoRf_1 <- MQTT-S DISCONNECT duration: 4000
20150227 152212.461 CWNAN0038I Disconnection request received from client XinoRf_1
20150227 152212.461 132 127.0.0.1:55701 XinoRf_1 -> MQTT-S DISCONNECT duration: 0 (0)
At this point Arduino sleeps appprox. 4 seconds
Arduino reconnects with clean session 0 - I believe all previous registrations should be kept by the broker
20150227 152217.519 132 127.0.0.1:55701 <- MQTT-S CONNECT cleansession: 0
20150227 152217.519 1998536376 127.0.0.1:55701 XinoRf_1 -> MQTT-S CONNACK returncode 0 (0)
20150227 152217.519 CWNAN0000I Client connected to udp port 1885 from XinoRf_1 (127.0.0.1:55701)
At this point Arduino is connecte
Here starts send a 2nd message in topic 1 - message never gets acknowledged by the broker.
20150227 152217.603 132 127.0.0.1:55701 XinoRf_1 <- MQTT-S PUBLISH msgid: 7 qos: 1 retained: 0
Following messages are resent by the client
20150227 152232.595 132 127.0.0.1:55701 XinoRf_1 <- MQTT-S PUBLISH msgid: 7 qos: 1 retained: 0
20150227 152247.575 132 127.0.0.1:55701 XinoRf_1 <- MQTT-S PUBLISH msgid: 7 qos: 1 retained: 0
20150227 152301.577 132 127.0.0.1:55701 XinoRf_1 <- MQTT-S PUBLISH msgid: 7 qos: 1 retained: 0
20150227 152317.536 132 127.0.0.1:55701 XinoRf_1 <- MQTT-S PUBLISH msgid: 7 qos: 1 retained: 0
20150227 152332.516 132 127.0.0.1:55701 XinoRf_1 <- MQTT-S PUBLISH msgid: 7 qos: 1 retained: 0
Впоследствии я обнаружил, что на eclipse.org (где сейчас поддерживается RSMB) есть несколько сообщений об ошибках, которые являются причиной такого поведения:
- Ошибка 424704 - брокер MQTT-SN забывает опубликованные темы
- Ошибка 430788 - когда клиент повторно подключается, он не получает сообщения из очереди
- Ошибка 430828 - если постоянство истинно для RSMB, клиент MQTT-SN не получает сообщения опубликовано до подключения
Михал