About the usage of the Last will and testament message in MQTT - mqtt

In my case, I use the last will message of MQTT to notify that some clients disconnect unexpectedly, such as the listening topic is "status".
My question is that when one client is connected to the brokerA, then disconnect unexpectedly from the brokerA, but it reconnects again to the brokerA, at the time, could there be one "last message" sent to the "status" topic?
Another question is that: when the last will message could be sent after one client disconnected from the broker unexpectedly.

There is a really good description of the LWT (Last Will and Testement) here:
http://www.hivemq.com/mqtt-essentials-part-9-last-will-and-testament/
But the simple version is as follows:
The broker will only deliver the LWT message under the following circumstances are met:
An I/O error or network failure is detected by the server.
The client fails to communicate within the Keep Alive time.
The client closes the network connection without sending a DISCONNECT
packet first.
The server closes the network connection because of a protocol error.

Related

Rollback Feature in MQTT Broker after message received from Broker

I have a Situation once message received from MQTT Broker, During processing the data , assume that DB is down and not completed the task. In that particular situation Data that received has to sent back to Broker that my task is not completed I mean rollback.
How to achieve this and how to tell broker that during processing the data some exception came and you need to send the data again.
can some one hep on this?
It can be done, but only with certain MQTT client libraries that allow you to take full control of the QOS handshake process.
Assuming a client has subscribed at QOS 1 or 2 to a topic it can then chose to hold of sending the PUBACK or PUBREC packet back to the broker. It can hold off completing the QOS handshake until the message has been fully processed. If the processing fails and the full handshake is not completed then the broker will try to redeliver the message again to the client so the client should go offline in the case of a failure so the broke will queue the message.
When the backend (datastore) comes back online the client can reconnect to the broker and the queued messages will be redelivered.

MQTT - How to know is message received by device

We have mqtt producer and consumer.
MQTT producer is at client level.
When we push message to producer, if the device is switched on, then it will receive the message.
If the device is switched off, then it wont receive the message until it turned on.
We need to know, when message sent to MQTT in server, if server is switched off, then we need to know the status as, it is queued or not received by server.
Based on it, we will send message for the user as, Please turn on device to do specific action.
Is there any better approach to know the status in MQTT to find is message is delivered or failed or queued to know server is active or not.
There is no end to end delivery notification in the MQTT protocol. Part of the pub/sub paradigm is that the publisher should be decoupled from the subscriber, there can be anywhere from 0 to many subscribers to a given topic.
There are 2 approaches to how to potentially work round this.
Have the subscriber respond on a separate topic to acknowledge that it has received the message. You will need to include a unique identifier in the message payload so it can be used in the response message.
You can use the Last Will and Testament feature of MQTT to have the subscriber maintain it's current status. When it starts it publishes a retained message to a known topic, e.g. publishes true to consumer/12345/status and sets a LWT to publish false if the device goes offline unexpectedly. It should also publish false if it cleanly shuts down. That way the publisher can check the status of the subscriber before deciding to publish the message.
I don't know which broker you are using. But in EMQ X MQTT broker, when QoS > 1, the message terminated delivered or ack broker will notify the server
The plugin: emqx-web-hook

MQTT - listen to ping, disconnect and connect events

I have "server side" mqtt client which I use to monitor and manage remote mqtt clients. I would like to extend this server module to keep tabs on the connectivity of the remote clients.
During normal operation, the remote clients regularly PING the broker, as per the broker logs:
1532924170: Received PINGREQ from c51
1532924170: Sending PINGRESP to c51
and when a disconnection occurs, the broker logs show this too:
1532924976: Client c51 has exceeded timeout, disconnecting.
1532924976: Socket error on client c51, disconnecting.
as well as the subsequent re-connection:
1532924978: New client connected from X.X.X.X as c51 (c1, k30).
1532924978: Sending CONNACK to c51 (0, 0)
I would like to monitor these 3 events from the mqtt-client held by the server module. Is this possible? If not, what alternative approach to "health" monitoring can you recommend?
No, you can not read these from a connected client.
The only pure MQTT approach is to make use of the Last Will and Testament (LWT) feature. You have the client set up a LWT publish a retained message to a client specific topic that marks it as offline. Then as the client connects it should publish a retained message to show you are online. If you disconnect cleanly (not triggered by keep alive time out you should manually publish the LWT message as the last thing before disconnecting).
It's also worth pointing out that ping messages only get sent if no other messages have been sent between the client and the broker in the keep alive period.

Failed PUBLISH Delivery in QoS1 MQTT

I am using the moquette mqtt broker, and I am trying to understand the implementation as well as the MQTT broker. I hope to make some modifications to the broker for a personal project.
I am curious what should happen when a device sends a PUBLISH msg to the broker, and the broker is unable to deliver the message to the subscribers. The protocol says that a PUBACK is sent back to the publisher. In the moquette source code this PUBACK seems to be sent after forwarding the message to any subscribers.
I commented out the sendPubAck() function to simulate that the message was not successfully published, so I assumed the publisher would publish the message again. However, when I add a print statement next to the incoming message handler function, I only see PINGREQ messages that are sent periodically from the publisher to the broker. I do not see any publish messages.
My question is the following: How exactly does a client device decide when to re-publish a message? Because commenting out the sendPubAck() function doesnt seem to make the publisher resend the message.
There are two choices. Firstly, you could add a message timeout parameter to trigger sending your PUBLISH again if a PUBACK is not received. Secondly, you could resend your PUBLISH only on reconnect.
I believe the second choice is the best option. The reason for this is down to the possible reasons why the broker (or client of course, depending on the direction of communication) hasn't responded.
You could have a buggy broker, which is effectively what you have created
There could have been a network failure (connection lost but not detected),
The broker could be overloaded.
For the first case there is nothing we can do, other than get the broker fixed. For the second case, the client must retry the publish when it reconnects. For the third case, sending a duplicate PUBLISH won't help the broker respond, it will just overload it further.
It's worth noting that the broker should not be waiting for the subscribing clients to respond before sending a PUBACK to the publishing client.

Losing messages over lost connection xmpp

i went through this question
Lost messages over XMPP on device disconnected
but there is no answer.
When a connection is lost due to some network issue then the server is not able to recognize it and keeps on sending messages to disconnected receiver which are permanently lost.
I have a workaround in which i ping the client from server and when the client gets disconnected server is able to recognize it after 10 sec and save further messages in queue preventing them from being lost.
my question is can 100% fail save message delivery be achieved by using some other way i know psi and many other xmpp client are doing it.
on ios side i am using xmppframework
One way is to employ the Advanced Message Processing (AMP) on your server; another one is to employ the Message Delivery Receipts on your clients.
The former one requires an AMP-enabled server implementation and the initiating client has to be able to tell the server what kind of delivery status reports it wants (it wants an error to be returned if the delivery is not possible). Note that this is not bullet-proof anyway as there is a window between the moment the target client losts its connectivity with the server and the moment the TCP stack on the server's machine detects this and tells the server about it: during this window, everything sent to the client is considered by the server to be sent okay because there's no concept of message boundaries in the TCP layer and hence if the server process managed to stuff a message stanza's XML into the system buffers of its TCP connection, it considers that stanza to be sent—there's no way for it to know which bits of its stream did not get to the receiver once the TCP stack says the connection is lost.
The latter one is bullet-proof as the clients rely on explicit notifications about message reception. This does increase chattiness though. In return, no server support for this feature is required—it's implemented solely in the clients.
go with XEP-0198 and enjoy...
http://xmpp.org/extensions/xep-0198.html
For a XMPP client I'm working on, the following mechanism is used:
Add Reachability to the project, to detect quickly when the phone is having connectivity problems.
Use a modified version of XEP-0198, adding a confirmation sent by the server. So, the client sends a message, the server confirms with a receipt. Later on, the receiving user will also confirm with a receipt. For each message you send, you get two confirmations, one from the server, one from the client. This requires modifications on the server of course.
When the app is not connected to the XMPP server, messages are queued.
When the app is logged in again to the XMPP server, the app takes all messages which were not confirmed by the server and sends them again.
For this to work, you have to locally store the messages in the app with three possible states: "Not sent", "Confirmed by server", "Confirmed by user"

Resources