How to handle multiple clients with same ID in mosquitto MQTT? - mqtt

How can I tell mosquitto MQTT what to do in case multiple persistent subscribers attempt to connect with the same client ID?
I accidentally ran into this situation when misconfiguring different testing environments which subscribed to the same broker. The result was that both subscribers got only part of the messages and the mosquitto log was spammed with "New connection from xxx" messages. Preferably the second subscriber would be rejected to make such a mistake apparent immediately.
I found a similar question for Solace and it seems to offer the option to either replace the older subscriber with the new one or reject the new one.
However when checking the available options for mosquitto.conf I could not see a similar option.

You don't.
The MQTT Spec says that client ids have to be unique and the correct behaviour is to kick the oldest one off and replace it with the new one.

Related

MQTT wildcard overlap topic filter causes the client to receive twice

When subscribing to a wildcard and a topic that overlaps that wildcard, the client receives twice the messages because of this overlapping behavior.
Example:
Client-A:
subscribe{aaa/bbb/+/ddd, aaa/bbb/ccc/ddd}
Then, if I publish something on the wildcard topic, Client-A will receive only one:
Client-B:
Publish{aaa/bbb/www/ddd, "blablabla"}
Client-A:
Received{aaa/bbb/www/ddd, "blablabla"}
But, if I publish on the specific topic, Client-A receives twice:
Client-B:
Publish{aaa/bbb/ccc/ddd, "blablabla"}
Client-A:
Received{aaa/bbb/ccc/ddd, "blablabla"}
Received{aaa/bbb/ccc/ddd, "blablabla"}
Checking the MQTT specification, it states this (source, page 36, section 3.3.5 Actions):
When Clients make subscriptions with Topic Filters that include wildcards, it is possible for a Client’s subscriptions to overlap so that a published message might match multiple filters. In this case the Server MUST deliver the message to the Client respecting the maximum QoS of all the matching subscriptions [MQTT-3.3.5-1]. In addition, the Server MAY deliver further copies of the message, one for each additional matching subscription and respecting the subscription’s QoS in each case.
If I use the Paho MQTT-SN Gateway (Server), then the server sends only once. But if I use the Eclipse Public Server, then I receive twice. The behavior is not consistent, or, at least, I cannot expect which behavior will be until I test it.
The question is: is it possible to set the specific behavior for the wildcard overlap to send only once? Or it depends on server-to-server implementation?
As the specification says that either behaviour is correct it becomes a choice for the broker implementers and likewise adding a configuration option to change the behaviour one way or the other would be a choice.
You will have to test any broker you are using and then consult their documentation to see if it is possible to change the behaviour.
There is no generic answer to this question.

LWT with user properties (timestamp): disconnect ungracefully

MQTT newbie here
Developing on .NET with MqttNet library for EMQX broker:
I am using MQTTv5 feature 'user properties' to add a timestamp to my messages when published. That is working flawlessly.
However, I need to stamp the LWT messages too.
In my connect method, I can supply an LWT including the timestamp user property.
Now, when I subscribe to my LWT topic using MQQTX desktop client; I get those messages and LWTs; so far so good.
But when I terminate my programs process (by that, disconnect ungracefully); I immediately get an LWT message. The problem being that my 'timestamp' user property has the stamp from when the connection was established (and LWT first set).
I could leave the value empty in my connect-method, so empty value = ungraceful disconnect; but thats not very elegant
Is there a possibility to intercept LWT messages sent from the broker, and set the timestamp?
EDIT:
I found the 'rules engine', it letting me use a broker-timestamp. But I could only add it to the payload so far (optimally it would be a user property)
I don't think so, it would be up to the broker to set the timestamp as it is what actually publishes the LWT message when it notices the client has gone.
I don't believe there is anything at the MQTT spec level (I really need to re-read the v5 message properties stuff) to do that, but it might be something that could be done with an appropriate plugin in the broker if it supports such things.

MQTT message subscription "all except me"

I'm writing a ServiceBus over MQTT protocol for a personal project.
I would basically like to subscribe every messages except the ones that comes from my instance.
I thought about doing a application side check, adding a "SenderId" property in my message.
But it has a considerable overhead in bandwidth consumption and also in compute time cause I have to check every single message if I'm the sender
I'm using basic topic family/message layout nothing complicated
I thought about using some kind of topic layout like : family/message/{senderIdHere}
But it looks like I'm wrong somewhere cause I would like to subscribe all
Here is a small example. That "EventPipeline" is somehow necessary to reduce code duplication between internal instance handling and over service bus handling
If anyone have some great hints,
Thanks by advance.
MQTT doesn't work that way, if you subscribe to a topic you normally get everything published to that topic.
The one possible option I can think of is to have everything publish to it's own sub topic e.g. family/message/{senderIdHere} and subscribe to the wildcard family/message/#
Then use ACLs to allow each user to publish (write) to their subtopic, but not be able to subscribe (read) from it. This will have the broker filter the messages for you.
Edit:
MQTT v5 introduced an option when subscribing to a topic to ignore the publisher's own messages. But this does require both the broker and the client to be using MQTT v5

Can mosquitto forward the ClientID of a messages sender?

I am using the mosquitto MQTT Broker.
Also, I have multiple (currently 10, but the number will increase) clients that publish some sensor data periodically to topic A. These clients are technically identical, but do have a unique identifier (serial number).
I also have a client that subscribes topic A in order to receive the published messages and persist the sensor valus in a database.
I certainly need to know which Sensor (i.e. client) has sent a particular value.
As a solution, one could just append some Sensor ID to the payload of each published message. But since the sensors access the broker via GSM, I need to keep the traffic low, so I am trying to avoid that.
I assume, the Broker itself knows which message comes from which client, especially when using perisistent connections, i.e. clean_session=False. Is that correct?
If yes, is there any chance that the subscribing clients can obtain the client_id when receiving the message?
Can it be configured in mosquitto? Or is it default behavior and I am missing something?
I am using paho-mqtt 1.3.1 for all clients.
No, the client id is not part of a published message. It is only used to identify the client to the broker when the connection is established in order to determine if stored messages and persistent subscriptions should be honoured.
The easiest solution is to use a separate topic for each sensor but with a shared root. e.g.
sensor 1 publishes to A/1
sensor 2 published to A/2
The client would then subscribe to A/+ this would then receive all the messages and can use the second half of the topic to determine which sensor it came from.
The other options is as you suggested which is to include the id in the payload.
Sending the client-id with payload(message) is possible. But you need to use delimiters in payload(message) at publisher side . Example: Publisher sends the payload as "client-ID=3 - temperature = 29 " . At the subscriber side , you remove the delimiters using strtok() .
There is no configuration available at broker side.
Per my experience with mosquitto, I don't think there is an option for mosquitto to change either the topic or the payload when re-publishing a received message.
However, I think it is just an implementation issue.
Theoretically, I think it is OK and good to support such kind of feature, since it does not violate MQTT specification at all.
(http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/csprd02/mqtt-v3.1.1-csprd02.html#_Toc385349773, Section 3.3.2.1)
However, since the Server is permitted to override the Topic Name,
it might not be the same as the Topic Name in the original PUBLISH Packet.
The pratical solution for your current problem is, as pointed by #hardillb, either publishing using different topics but receiving using a topic with wildcard (+ or #), or, containing publisher information in payload.

messages not retained in Apollo server

I have a problem by using fusesource code to publish mqtt messages to Apollo server.
I wrote the message publisher with the code like the following
connection.publish(topic, message.getBytes(),QoS.AT_LEAST_ONCE, true);
I also wrote the message consumer which subscribes to the topic. If I started my consumer first and then the publisher, the consumer can obtain all messages correctly. However, if I start the publisher first and then the consumer, the consumer will not receive the messages.
Also, I went into Apollo admin console and I could not find any messages in the queue. (Please see attached screen shot).
What should I do to fix this problem? I could not make my consumer running all the time and I don’t want to lose any messages from the publisher. Should not the broker (Apollo) keep all the messages when the consumers are offline? If yes, how come I could not see it?
This seems a silly question but I am pretty new to MQTT and I do need some help.
I suspect the topic is being auto deleted once there are no producers or consumers attached to the topic. To disable auto delete 'feature', add the following XML element within the virual_host config element in apollo.xml:
<topic auto_delete_after="0"/>
Future versions of apollo will avoid deleting the topic when holds a retained message APLO-319 .
This seems like a bug, since you have marked the messages as retained. However, I do not know how Apollo behaves regarding multiple retained messages on a topic. You may want to raise this on their mailing list.

Resources