← index #296Issue #157
Related · high · value 0.607
QUERY · ISSUE

If any possible to make umqtt to support Qos 2?

openby Jim43opened 2018-07-30updated 2024-08-25

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

5 comments
ebeem · 2018-08-28

I am interested to know too
qos 2 is needed sometimes

SpotlightKid · 2018-08-31

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 · 2018-09-02

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

Jim43 · 2018-09-03

@SpotlightKid Thank You ! that's pretty awesome

jonnor · 2024-08-25

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

CANDIDATE · ISSUE

check_msg() fails when subscribed message has QOS

closedby diginfoopened 2017-02-28updated 2017-04-14

If a message was sent with the QOS set and the client subscribes to the topic, the client subsequently fails when calling check_msg().

5 comments
diginfo · 2017-04-05

@pfalcon - I am not sure what additional info you need for this ?

  1. Subscribe to Topic on Broker

  2. Using another Client, publish a message with QOS = 2

  3. mqtt-simple crashes while checking message:

     checking...
     Traceback (most recent call last):
       File "<stdin>", line 1, in <module>
       File "dev/mqtest.py", line 32, in <module>
       File "dev/mqtest.py", line 20, in connect
       File "/lib/umqtt_simple.py", line 192, in check_msg
       File "/lib/umqtt_simple.py", line 185, in wait_msg
     AssertionError:
    
dpgeorge · 2017-04-07

Running the unix version of uPy, using the provided example_sub.py code in this repo (both blocking and non-blocking mode), and publishing a message with QoS 0, 1 or 2 works fine for me (the message is received).

@diginfo you'll need tos pecify your platform, the code you are using, and the version of umqtt (because line 185 is blank in the current version so can't have an AssertionError).

diginfo · 2017-04-07

Thanks, I reported this about 6 weeks ago and have not updated to the latest code, maybe it has been fixed - later today I will test the latest version but can't do that right now.

It was (and still is) working flawlessly when the QOS was not set, but as soon as I set the QOS and sent a message from another client the 8266 crashed.

I just checked and the line in question is line 184, I probably added a comment into my copy of this file which shifted everything down a line.

This is my class code snippet that connects and checks for messages:

	self.client.set_callback(self.subcb)
	
	def subcb(self,topic,msg):
		... do stuff

	def connect(self):
	  for i in range(3):
	    try:
	      self.client.connect()
	      if(self.debug): print(gv.config['broker_host'] + ' connected.')
	      self.client.subscribe(gv.config['get_topic'])
	      time.sleep_ms(100) ## IMPORTANT
	      self.client.check_msg()
	      break
	    except Exception as err:
	      self.error(err)
	      time.sleep(2)
diginfo · 2017-04-07

Later I will put together a complete example rather than just bits & pieces

diginfo · 2017-04-14

I am closing this issue as having created some test code, I am now unable to replicate the issue with QOS 1 or 2.

Sorry about that.

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied