eclipse / mosquitto

Eclipse Mosquitto - An open source MQTT broker
https://mosquitto.org
Other
8.89k stars 2.37k forks source link

persistent connections: messages for disconnected clients that connected with procotol MQTT v5.0 are not queued #1728

Closed nduhme closed 4 years ago

nduhme commented 4 years ago

I tested persistent connections with mosquitto 1.6.10 and seem to have found a problem when the Protocol Version is set to MQTT 5.0. When MQTT 5.0 is used Mosquitto seems to forget any information of the connection when the connection to the client is lost, by a socket error for example.

Steps to repoduce:

a) Protocol Version MQTT 3.1.1 => no problem 1 – Connect subscriber client to Mosquitto broker with Protocol Version MQTT v3.1.1 2 – Subscribe to topic # with QoS1 3 – disconnect subscriber client / close client program to provoke socket error 4 – publish to any topic with QoS1 => messages queued 5 - reconnect subscriber client (no Clean Start) => queued messages are sent to client

b) Protocol Version MQTT 5.0 => problematic case 1 – Connect subscriber client to Mosquitto broker with Protocol Version MQTT v5.0 2 – Subscribe to topic # with QoS1 3 – disconnect subscriber client / close client program to provoke socket error 4 – publish to any topic with QoS1 => message NOT queued? 5 - reconnect subscriber client (no Clean Start) => no messages are sent to client

Example console output of mosquitto broker a) client1 is publisher, MQTTX_311 is subriber, all queued messages are received after reconnecting (step 5)

1592474749: mosquitto version 1.6.10 starting 1592474749: Config loaded from mosquitto.conf. 1592474749: Opening ipv6 listen socket on port 1883. 1592474749: Opening ipv4 listen socket on port 1883. 1592474753: New connection from 127.0.0.1 on port 1883. 1592474753: New client connected from 127.0.0.1 as client1 (p2, c0, k60). 1592474753: No will message specified. 1592474753: Sending CONNACK to client1 (0, 0) 1592474756: New connection from 127.0.0.1 on port 1883. 1592474756: New client connected from 127.0.0.1 as MQTTX_311 (p2, c0, k60). 1592474756: No will message specified. 1592474756: Sending CONNACK to MQTTX_311 (0, 0) 1592474765: Received SUBSCRIBE from MQTTX_311 1592474765: # (QoS 1) 1592474765: MQTTX_311 1 # 1592474765: Sending SUBACK to MQTTX_311 1592474770: Socket error on client MQTTX_311, disconnecting. 1592474773: Received PUBLISH from client1 (d0, q1, r0, m1, 'home/test1', ... (4 bytes)) 1592474773: Sending PUBACK to client1 (m1, rc0) 1592474777: Received PUBLISH from client1 (d0, q1, r0, m2, 'home/test1', ... (5 bytes)) 1592474777: Sending PUBACK to client1 (m2, rc0) 1592474777: Received PUBLISH from client1 (d0, q1, r0, m3, 'home/test1', ... (5 bytes)) 1592474777: Sending PUBACK to client1 (m3, rc0) 1592474781: Received PUBLISH from client1 (d0, q1, r0, m4, 'home/test1', ... (5 bytes)) 1592474781: Sending PUBACK to client1 (m4, rc0) 1592474792: New connection from 127.0.0.1 on port 1883. 1592474792: New client connected from 127.0.0.1 as MQTTX_311 (p2, c0, k60). 1592474792: No will message specified. 1592474792: Sending CONNACK to MQTTX_311 (1, 0) 1592474792: Sending PUBLISH to MQTTX_311 (d0, q1, r0, m1, 'home/test1', ... (4 bytes)) 1592474792: Sending PUBLISH to MQTTX_311 (d0, q1, r0, m2, 'home/test1', ... (5 bytes)) 1592474792: Sending PUBLISH to MQTTX_311 (d0, q1, r0, m3, 'home/test1', ... (5 bytes)) 1592474792: Sending PUBLISH to MQTTX_311 (d0, q1, r0, m4, 'home/test1', ... (5 bytes)) 1592474792: Received PUBACK from MQTTX_311 (Mid: 1, RC:0) 1592474792: Received PUBACK from MQTTX_311 (Mid: 2, RC:0) 1592474792: Received PUBACK from MQTTX_311 (Mid: 3, RC:0) 1592474792: Received PUBACK from MQTTX_311 (Mid: 4, RC:0)

b) client1 is publisher, MQTTX_5 is subriber, 0 messages are received after reconnecting (step 5) 1592475088: mosquitto version 1.6.10 starting 1592475088: Config loaded from mosquitto.conf. 1592475088: Opening ipv6 listen socket on port 1883. 1592475088: Opening ipv4 listen socket on port 1883. 1592475093: New connection from 127.0.0.1 on port 1883. 1592475093: New client connected from 127.0.0.1 as client1 (p2, c0, k60). 1592475093: No will message specified. 1592475093: Sending CONNACK to client1 (0, 0) 1592475099: New connection from 127.0.0.1 on port 1883. 1592475099: New client connected from 127.0.0.1 as MQTTX_5 (p5, c0, k60). 1592475099: No will message specified. 1592475099: Sending CONNACK to MQTTX_5 (0, 0) 1592475109: Received SUBSCRIBE from MQTTX_5 1592475109: # (QoS 1) 1592475109: MQTTX_5 1 # 1592475109: Sending SUBACK to MQTTX_5 1592475111: Socket error on client MQTTX_5, disconnecting. 1592475113: Received PUBLISH from client1 (d0, q1, r0, m1, 'home/test1', ... (4 bytes)) 1592475113: Sending PUBACK to client1 (m1, rc0) 1592475115: Received PUBLISH from client1 (d0, q1, r0, m2, 'home/test1', ... (5 bytes)) 1592475115: Sending PUBACK to client1 (m2, rc0) 1592475118: Received PUBLISH from client1 (d0, q1, r0, m3, 'home/test1', ... (5 bytes)) 1592475118: Sending PUBACK to client1 (m3, rc0) 1592475120: Received PUBLISH from client1 (d0, q1, r0, m4, 'home/test1', ... (5 bytes)) 1592475120: Sending PUBACK to client1 (m4, rc0) 1592475132: New connection from 127.0.0.1 on port 1883. 1592475132: New client connected from 127.0.0.1 as MQTTX_5 (p5, c0, k60). 1592475132: No will message specified. 1592475132: Sending CONNACK to MQTTX_5 (0, 0)

I tried this with 2 different open source clients to make sure it is not the subscriber clients fault. Maybe i overlooked some information that MQTT 5.0 handles disconneting clients differently... ?

ralight commented 4 years ago

MQTT v3.1.1 has the "clean session" flag, which controls whether a client session is cleared both when the client connects and disconnects.

MQTT v5.0 has the "clean start" flag, which controls whether a client session is cleared when the client connects only. For disconnects, MQTT v5 uses the session-expiry-interval property, which is set to 0 (expire immediately) if not set.

So yes, the behaviour changed between the two specs. I imagine this is what you are seeing.

nduhme commented 4 years ago

Hello ralight, thank you very much for your fast response. I tested setting the session-expiry-interval and it worked as expected.

Example console output of mosquitto broker client1 is publisher, listener01 using MQTT 5 is subriber, connected with session-expiry-interval set to 10000 => all messages are received after reconnecting

1592546131: mosquitto version 1.6.10 starting 1592546131: Config loaded from mosquitto.conf. 1592546131: Opening ipv6 listen socket on port 1883. 1592546131: Opening ipv4 listen socket on port 1883. 1592546214: New connection from 127.0.0.1 on port 1883. 1592546214: New client connected from 127.0.0.1 as listener01 (p5, c0, k60). 1592546214: No will message specified. 1592546214: Sending CONNACK to listener01 (0, 0) 1592546214: Saving in-memory database to mosquitto.db. 1592546250: New connection from 127.0.0.1 on port 1883. 1592546250: New client connected from 127.0.0.1 as client1 (p2, c0, k60). 1592546250: No will message specified. 1592546250: Sending CONNACK to client1 (0, 0) 1592546281: Received SUBSCRIBE from listener01 1592546281: # (QoS 2) 1592546281: listener01 2 # 1592546281: Sending SUBACK to listener01 1592546286: Socket error on client listener01, disconnecting. 1592546289: Received PUBLISH from client1 (d0, q2, r0, m1, 'home/test1', ... (0 bytes)) 1592546289: Sending PUBREC to client1 (m1, rc0) 1592546289: Received PUBREL from client1 (Mid: 1) 1592546289: Sending PUBCOMP to client1 (m1) 1592546290: Received PUBLISH from client1 (d0, q2, r0, m2, 'home/test1', ... (0 bytes)) 1592546290: Sending PUBREC to client1 (m2, rc0) 1592546290: Received PUBREL from client1 (Mid: 2) 1592546290: Sending PUBCOMP to client1 (m2) 1592546290: Received PUBLISH from client1 (d0, q2, r0, m3, 'home/test1', ... (0 bytes)) 1592546290: Sending PUBREC to client1 (m3, rc0) 1592546290: Received PUBREL from client1 (Mid: 3) 1592546290: Sending PUBCOMP to client1 (m3) 1592546329: New connection from 127.0.0.1 on port 1883. 1592546329: New client connected from 127.0.0.1 as listener01 (p5, c0, k60). 1592546329: No will message specified. 1592546329: Sending CONNACK to listener01 (1, 0) 1592546329: Saving in-memory database to mosquitto.db. 1592546329: Sending PUBLISH to listener01 (d0, q2, r0, m1, 'home/test1', ... (0 bytes)) 1592546329: Sending PUBLISH to listener01 (d0, q2, r0, m2, 'home/test1', ... (0 bytes)) 1592546329: Sending PUBLISH to listener01 (d0, q2, r0, m3, 'home/test1', ... (0 bytes)) 1592546329: Received PUBREC from listener01 (Mid: 1) 1592546329: Sending PUBREL to listener01 (m1) 1592546329: Received PUBREC from listener01 (Mid: 2) 1592546329: Sending PUBREL to listener01 (m2) 1592546329: Received PUBREC from listener01 (Mid: 3) 1592546329: Sending PUBREL to listener01 (m3) 1592546329: Received PUBCOMP from listener01 (Mid: 1, RC:0) 1592546329: Received PUBCOMP from listener01 (Mid: 2, RC:0) 1592546329: Received PUBCOMP from listener01 (Mid: 3, RC:0)