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

If any possible to make umqtt to support Qos 2? #296

Open
Jim43 opened this issue Jul 30, 2018 · 5 comments
Open

If any possible to make umqtt to support Qos 2? #296

Jim43 opened this issue Jul 30, 2018 · 5 comments

Comments

@Jim43
Copy link

Jim43 commented Jul 30, 2018

Look through the Doc and code, i found Qos=2 messages are not supported in umqtt module.It's good to keep the code size small,but this function will make this module more larger ? i am curious

@ebeem
Copy link

ebeem commented Aug 28, 2018

I am interested to know too
qos 2 is needed sometimes

@SpotlightKid
Copy link
Contributor

Yes, implementing support for QOS 2 will increase the code size of the umqtt.simple module. Currently the publish method only handles QOS 0 and 1 and the logic for receiving PUBLISH packet from the server in the wait_msg method also only handles QOS 0 and 1.

For QOS 1 the method has to listen for a PUBACK packet from the server after it sends a PUBLISH packet.

For QOS 2 the client, after sending the PUBLISH packet, has to listen for a PUBREC packet from the server, then send a PUBREL packet and then listen for a PUBCOMP packet.

The simplistic way to implement this would be to handle all this in a synchronous, blocking fashion, i.e. for publishing client -> server, in the method publish replace the assert in line 142 with somethings like this (pseudo code):

while  True:
    opcode = wait_msg()
    if opcode == PUBREC:
        paket = read_packet()
        if paket.paket_id == packet__id:
            break
send_pubrel()
while  True:
    opcode = wait_msg()
    if opcode == PUBCOMP:
        paket = read_packet()
        if paket.paket_id == packet__id:
            break

And for receiving QOS 2 from server -> client, do something like this in the wait_msg method at line 197:

send_pubrec()
while  True:
    opcode = wait_msg()
    if opcode == PUBREL:
        paket = read_packet()
        if paket.paket_id == packet__id:
            send_pubcomp()
            break

The problem with this is:

  • If the server doesn't send the PUBREC or PUBCOMP resp. the PUBREL package, the client will block forever (same it does currently with QOS 1, if no PUBACK is received)-.
  • If the server sends any other packets with QOS 1 or 2 in between, which the spec allows, the client will get confused and probably end up in a dead lock.

The only way I see around these problems is handling reception of all packet types in wait_msg and passing them to different callback methods. But that would a) make a record of sent and received packet ids necessary (which increases memory requirements) and b) go against the stated goal of the module to avoid "callback hell".

@ebeem
Copy link

ebeem commented Sep 2, 2018

@SpotlightKid Thank you so much!!
this was so helpful indeed, my gratitude.

@Jim43
Copy link
Author

Jim43 commented Sep 3, 2018

@SpotlightKid Thank You ! that's pretty awesome

@jonnor
Copy link

jonnor commented Aug 25, 2024

Is this still relevant? Are there other MQTT implementations that people know of that support QoS 2 ?

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

4 participants