MQTT wildcard overlap topic filter causes the client to receive twice - mqtt

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.

Related

How one client can know about presence of another client in mqtt

It is possible to get notify when another client was connected to same topic which is subscribed by same topic in mqtt.
ex: a client subscribed to : app/id another client also subscribed to app/id then both clients will get a message about number of clients subscribed to this particular topic.
if it is possible then please let me know.
The whole point of a pub/sub architecture is to unlink the producer of information (publisher) from the consumer (subscriber). Producers just publish to a topic and the broker deals with routing that message to any consumers that may have a matching topic pattern subscription.
There is no way to count how many clients may receive a given message at any particular time for the following reasons:
A subscriber may be using a wildcard topic pattern that happens to match the topic of the published message.
A subscriber may have a persistent session with a matching topic pattern but if currently off line and will receive the queued message when it next connects
With shared subscriptions there could be any number of clients pooled together subscribed to a given topic pattern, but only one of them will receive any given message as they are load balanced round the group.
There is no guarantee that there are ever any subscribers, in the same way there is no end to end delivery guarantee only between a single client and the broker.
In a sensibly implemented broker, subscription topic pattern matches are only evaluated when a new message is published, so the best you could ever get is how many clients the last message with a given topic was delivered to, as there is no efficient way to calculate the number in advance.
In the same way as your last question about topics, if you think knowing this is required then you need to rethink your design or your use of MQTT.

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

How to handle multiple clients with same ID in mosquitto 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.

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.

how to sanitize mqtt message payload in server side?

I made an instant messaging app using MQTT protocol.
I want to add some extra data about messages in payload like sent time ( server time not client time ) and also provide kind of server side payload sanitizing.
Is it a good idea to add a third party client with superuser privileges between message sender and message receiver on broker's local machine to do this job ?
or is there any better idea ?
by the way I'm using EMQTT as message broker.
From a pure security view having direct peer to peer traffic (without filtering and sanitising) sounds like a dangerous idea. (At least in the Internet-of-things domain I would clearly object against it.)
Why? Because the clients are outside of your control (i.e. a hacker can re-engineer) and inject any traffic to exploit security holes on the receiving side of other clients.
So sanitising on the server side sounds like a very good idea.
I would suggest two topics: One (inbound) topic the clients use to publish messages, and another (outbound) topic used by clients to subscribe to messages. A server side component would then read the messages from inbound topic, sanitize it and publish to the outbound topic.
This de-coupeling makes it also easier to introduce MQTT payload changed: If you update the payload in a non-compatible way, introduce a new inbound topic and keep the old inbound topic too. This allows you to support old and new clients during the transition phase.

Resources