Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MQTT message duplicated after automatic reconnection #121

Open
freyssin opened this issue Feb 26, 2020 · 0 comments
Open

MQTT message duplicated after automatic reconnection #121

freyssin opened this issue Feb 26, 2020 · 0 comments

Comments

@freyssin
Copy link

Even if this problem seems similar to the previous one I submitted (#120), I think it is not. It manifests in the same way (duplication of messages after an automatic reconnection) but the cause seems different. First of all, in my previous post the problem concerns a publisher, whereas in this case it is a subscriber. Secondly, in this test we stop, and then restart the server.

We have a client that subscribes on a topic with QoS2 in a durable session (cleanSession= false). This client uses the FuseSource client through the callback API, with automatic reconnection feature. This test works correctly in the absence of failure, but we sometimes detect duplicated messages when the server stops, then restarts.

In the table below we reproduce the sequence of messages before and after the network failure (If necessary we have a wireshark capture of this sequence). As explained below it seems that the problem comes from the takeover of the client.

  Server (frames sent) Client (frames sent) Client (stdout)
1 PUBLISH #44    
2   PUBREC #44 Receive #44
3 == Server Stop/Restart == == Server Stop/Restart ==  
4   CONNECT  
5 CONNACK    
6   SUBSCRIBE  
7 PUBLISH #44 (DUP)    
8   PUBREC #44 Receive #44
9 PUBLISH #45    
10   PUBREC #45 Receive #45
11 SUBACK    
12 PUBREL #44    
13   PUBCOMP #44  
14 PUBREL #45    
15   PUBCOMP #45  

Before the failure, message #44 is received by the client and the corresponding PUBREC is sent in response before the flow is interrupted. The message is delivered to the client (printed on stdout, line 2 of the table above).

This behavior complies with the specification which authorizes the delivery of the message either when the PUBLISH is received, or when the PUBREL is received.

After the failure, the server sends anew the message #44. This corresponds to the case where the server has not received the PUBREC. In fact the message has been received at TCP level but has not been processed before the failure. The duplicated message #44 is acknowledged by the client with a new PUBREC. This behavior also complies with the specification.

The problem comes with message #44 being re-delivered to the client (line 9). The client is expected to store the id (#44) of the message before it sends the PUBREC, and to release this id only when it receives the PUBREL. In the present case the client did send PUBREC #44 and did not receive PUBREL #44 before the failure, so it would not have released the identifier #44. After the failure, when message #44 was returned, it should have detected that he had already received and delivered this message, so it should not deliver it again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant