MQTT message subscription "all except me" - mqtt

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

Related

Does MQTT Support User to User Messages

I know that using MQTT topics devices can subscribe to them. But is there any way that a IoT device can send some message to a target IoT device (by device id or something) without using a topic or is there any standard topic for this scenario?
There is no way to communicate without a topic, but you can create a topic for any purpose. So typically if you wanted to send a message to another client, you would publish it somewhere in the hierarchy of topics to which that client is subscribed.
That could be as simple as something like device/12345/inbound or whatever you prefer. And because topics can have hierarchy, in addition to whatever detail you put in the body, you can also encode categorization of your message into the topic, much as RESTful APIs often do in a URL.
A good reason for using target-specific (or owner-account-specific) topics is that the most easy solutions for MQTT security compartmentalization are topic-scope.

mqtt client subcribing to multiple subscriptions. whats the best way?

I am building a javascript app which is going to be a mqtt client. It needs to subscribe to multiple topics. I can see that there are two ways to implement this.
Make multiple client connections. On each client connection subscribe on a single topic. Then the onMessage handler will be fired on that client for that topic only. This means I will have multiple mqtt connections.
Make a single client connection. Subscribe to multiple topics on that one client. Then when onMessage fires, I need to inspect the message.topic and route that message to the subscriber callback method which subscribed to that topic and I need to cater for the # and * wildcards.
Currently I am implementing method #2. But I would like to get your opinions on which is the best method and why.
Option 1 is REALLY not a good idea, it just makes so much extra work, maintaining the connection for all the separate clients and adds extra overhead to the broker.

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.

How do I differentiate between MQTT Publish events originating from Users vs internal messages meant to broadcast only

I am using mosquitto mqtt client.
For example, you have users that publish and subscribe to topics. The topic actually correlates to a REsT endpoint.
Scenario 1 (typical pub/sub usage)
UserA subscribes to topic /device/123/meta
UserB publishes some data to topic /device/123/meta
by definition, this publish is broadcasted out to the subscribers
we have a script subscribed to /devices/# which knows how to save the payload for the topic /device/123/meta when it receives publish'ed data. This data is saved to the database.
Scenario 2
Someone updates data /device/123/meta via a ReST interface (or a direct DB update, the key is it's not a MQTT publish).
database is updated
a publish message is sent to the MQTT broker so that all subscribers get the updates as a payload
Scenario 2 is what I'm trying to wrap my head around. This creates a nasty feedback loop. When internal messages are broadcasted out, my script to deal with publish events from users can't differentiate between publish events originating from a 3rd party user or an internal publish event only meant to broadcast out some data (with no saving of data needed).
How should I handle this? The MQTT message is very simplistic and I'm not finding anything I can base logic off of. I'm trying to explore using the origin somehow, but no luck this far. I realize I can write plugins, but this is quite the task for mosquitto.
There is no way to distinguish where a message originated from the subscriber at a pure MQTT protocol level. Part of the point of a pub/sub protocol is to decouple publishers from subscribers.
The most portable way to do this would be to add a flag to the actual message payload to indicate that message originated from somewhere other than the actual device.
Or assuming the message is being published as a result a trigger in the database have the trigger check if the incoming message actually changed the database stored value, if the incoming messages matches the existing state of the DB then there is no need to republish it.
Mosquitto's plugin mechanism is currently only for writing authentication and authorisation solutions, but the JavaScript mosca or Java HiveMQ brokers support plugins that may be able to do what you want.

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