LabVIEW-Open-Source / MQTT-Client

A LabVIEW-based client for MQTT
Other
27 stars 5 forks source link

QoS2: No PUBCOMP packet is send from client #18

Open JohRup opened 2 years ago

JohRup commented 2 years ago

I am facing some problems using QoS 2. I adapted one of your templates for this purpose. The result looks not like it should look like. No PUBCOMP is send from the client to the broker. Attached is a detail of the command line of the broker (additional information: This broker is bridged with another broker from which data is received with QoS 2 as well).

After few to LabVIEW published packages (max_inflight_messages), no further packages are published. Connection remains stable.

1664285329: Received SUBSCRIBE from LabVIEW 1664285329: IMWind/ACC (QoS 2) 1664285329: LabVIEW 2 ACC 1664285329: Sending SUBACK to LabVIEW 1664285329: Received PUBLISH from WIND.bridge-01 (d0, q2, r0, m38661, 'ACC', ... (368 bytes)) 1664285329: Sending PUBREC to WIND.bridge-01 (m38661, rc0) 1664285329: Received PUBREL from WIND.bridge-01 (Mid: 38660) 1664285329: Sending PUBLISH to LabVIEW (d0, q2, r0, m1, 'ACC', ... (367 bytes)) 1664285329: Sending PUBCOMP to WIND.bridge-01 (m38660) 1664285329: Received PUBREC from LabVIEW (Mid: 1) 1664285329: Sending PUBREL to LabVIEW (m1) 1664285329: Received PUBREL from WIND.bridge-01 (Mid: 38661) 1664285329: Sending PUBLISH to LabVIEW (d0, q2, r0, m2, 'ACC', ... (368 bytes)) 1664285329: Sending PUBCOMP to WIND.bridge-01 (m38661) 1664285329: Received PUBLISH from WIND.bridge-01 (d0, q2, r0, m38662, 'ACC', ... (365 bytes)) 1664285329: Sending PUBREC to WIND.bridge-01 (m38662, rc0) 1664285329: Received PUBREC from LabVIEW (Mid: 2) 1664285329: Sending PUBREL to LabVIEW (m2) 1664285329: Received PUBLISH from WIND.bridge-01 (d0, q2, r0, m38663, 'ACC', ... (362 bytes)) 1664285329: Sending PUBREC to WIND.bridge-01 (m38663, rc0) 1664285329: Received PUBREL from WIND.bridge-01 (Mid: 38662) 1664285329: Sending PUBLISH to LabVIEW (d0, q2, r0, m3, 'ACC', ... (365 bytes)) 1664285329: Sending PUBCOMP to WIND.bridge-01 (m38662) 1664285329: Received PUBREC from LabVIEW (Mid: 3) 1664285329: Sending PUBREL to LabVIEW (m3) 1664285329: Received PUBREL from WIND.bridge-01 (Mid: 38663) 1664285329: Sending PUBLISH to LabVIEW (d0, q2, r0, m4, 'ACC', ... (362 bytes)) 1664285329: Sending PUBCOMP to WIND.bridge-01 (m38663) 1664285329: Received PUBLISH from WIND.bridge-01 (d0, q2, r0, m38664, 'ACC', ... (364 bytes)) 1664285329: Sending PUBREC to WIND.bridge-01 (m38664, rc0) 1664285329: Received PUBREC from LabVIEW (Mid: 4) 1664285329: Sending PUBREL to LabVIEW (m4)

Is there some mechanism I don't get right or is there any bug?

francois-normandin commented 2 years ago

Are you talking about the client or the broker? PUBCOMP is supposed to be sent from the broker.

image

JohRup commented 2 years ago

Thanks for your quick reply. In my case, the broker publishes to the client (LabVIEW) as this broker is the bridge.

I extracted the relevant parts to make it clear:

1664285329: Sending PUBLISH to LabVIEW (d0, q2, r0, m1, 'ACC', ... (367 bytes)) 1664285329: Received PUBREC from LabVIEW (Mid: 1) 1664285329: Sending PUBREL to LabVIEW (m1) missing PUBCOMP from LabVIEW client 1664285329: Sending PUBLISH to LabVIEW (d0, q2, r0, m2, 'ACC', ... (368 bytes)) 1664285329: Received PUBREC from LabVIEW (Mid: 2) 1664285329: Sending PUBREL to LabVIEW (m2) missing PUBCOMP from LabVIEW client 1664285329: Sending PUBLISH to LabVIEW (d0, q2, r0, m3, 'ACC', ... (365 bytes)) 1664285329: Received PUBREC from LabVIEW (Mid: 3) 1664285329: Sending PUBREL to LabVIEW (m3) *missing PUBCOMP from LabVIEW client

jaddik commented 1 year ago

I am seeing the same thing, there is a bug with subscribing with a QoS =2. To reproduce, set both publish and subscribe to Qos = 2 and publish data. After about 20 messages the user event from a publish does not happen anymore. the subscribe just stops for that topic, unsubscribe/subscribe does not fix or work after.

JohRup commented 1 year ago

@jaddik, thanks for making this clear. I actually did not solve the problem so far and hope that your comment will lead to a solution.

VVVVVane commented 1 week ago

Add a PUBREL case in Handle Incoming Packets.vi may help. 20241104160533

francois-normandin commented 1 week ago

@VVVVVane PUBREL can only be received by the broker, so the client would never have to handle this packet type as a valid incoming packet. As such, it is handled in its counterpart >> MQTT Server.lvlib:Server.lvclass:Handle Incoming Packets.vi

VVVVVane commented 1 week ago

Snipaste_2024-11-05_09-42-18 But I think if the client receives a subscription message ,it needs to handle the PUBREL packet,so that the broker can complete this message transmission. @francois-normandin

lishan148 commented 1 week ago

In the MQTT protocol, if you are a subscribing client and receive a message with QoS 2, you indeed need to reply with PUBCOMP. This is because QoS 2 guarantees "exactly once" delivery of messages, which involves a four-step acknowledgment process.

QoS 2 Message Acknowledgment Process

  1. PUBLISH: The publisher sends a PUBLISH message with QoS 2.
  2. PUBREC: The receiver (subscriber or broker) acknowledges receipt of the message by sending a PUBREC packet.
  3. PUBREL: The publisher, upon receiving PUBREC, sends a PUBREL packet to release the message's Packet ID.
  4. PUBCOMP: The receiver sends a PUBCOMP packet after receiving PUBREL to confirm that the processing is complete.

Key Points

Therefore, as a subscribing client, if you receive a message with QoS 2, you must reply with PUBCOMP to complete the acknowledgment process and ensure the accurate delivery of the message.

francois-normandin commented 1 week ago

@VVVVVane I see what you mean. That makes sense. The broker will wait for the PUBCOMP packet to dispose of the PUBLISH message, so it could be holding it off and disconnect the client after a while due to protocol failure. There is no harm in trying. You can simply add a Prepare Response Packet dynamic dispatch VI in the MQTT_Base and see what happens.

Worse case scenario, we need a specific override in the Client Handle Request to store/discard IDs (and prevent race conditions in reservation of IDs for reuse) Best case scenario, we just need the Prepare Response call in the default case of the Base...

image

lishan148 commented 1 week ago

As a subscribing client in MQTT, if you do not reply with PUBCOMP after receiving a message with QoS 2, the flight window will continue to increase while waiting for the acknowledgment.