I am trying to subscribe to multiple topic levels in the configuration file and the aim is whenever I launch the MQTT, the broker has those topics, after which when I enter a wild card it string compare and checks if the topic is on the broker and if yes it extracts the data and if not it jumps to the next branch level
I have tried to write a level topic tree but dont know how to subscribe in the config file, as I am most sure if mosquitto.subscribe will work there or not
Below shows the snippet of the topic tree,
tree is the root node,
sub_branch = tree/sub_branch;
sub_branch_1 = tree/sub_branch_1;
branch_1 = tree/branch/branch_1;
branch_2 = tree/branch/branch_2;
After launch, the topics are on the broker and I use wildcard
tree/#;
this should give me data for all the branches
and if topic = tree/ranch; its an error(wrong topic) and ask for the next one
Any help is much much appreciated!
You do NOT configure topics on the broker, the broker has no knowledge of what topics a client might publish messages to or what topics a client might subscribe to (apart from in any Access Control Lists).
As far as the broker is concerned topics don't exist until a client publishes a message, at which point it does the following things in order:
Checks the ACL for that user/client if one exists to see if there is a pattern matching the incoming topic and accepts or discards the message if there is a match
Assuming it accepts the message it then searches the list of topic patterns for all subscribed clients.
If there is a match for a client it checks that client's/user's ACL to see if there is a match and if allowed sends that message to the client.
Related
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.
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.
I would like to have a "default" client that gets all MQTT messages on topics that no one subscribed to. Is that possible?
I read about $SYS topics but they don't seem to provide a solution.
No, it is not possible to know what topics every other client is subscribed to easily/in a browser independent way. You may be able to build a list of what topics clients are subscribed to from the info in the $SYS/# topic tree on some broker implementations, but that won't help you find the inverse, which is what you are asking for.
The only option would be to subscribe with the wildcard topic of #. This would get all (assuming no ACLs in place) messages published to all topics.
If you could build the list I mentioned in the fist paragraph then you could use this as a filter.
Is it possible to that two clients are subscribed to same topic in MQTT broker. And based on authorization, some of the massages are sent to one client and not other (subscribed on same topic).
No
Any number of clients can be subscribed to a given topic, but you can not limit which of those clients can receive messages on that topic on a per message basis. It is all the topic or none.
There is no direct solution for this approach. But however I have a workaround for this solution.
Say you have two client with ClientId: 1 and 2
Say your topic structure is : stackoverflow/data/{Client-ID}/sensor/ingress
While defining the authorization parameter you can assert with the permission as +/+/{Client-ID}/+/+
This will make sure that, the topic structure will remain the same, but at the same time, the client will be able to publish and subscribe data only from their own topics.(topics which have their client-Id).
i have four trucks connected to a mqtt broker, and I have four Apps/devices. the trucks publishes messages and the Apps subscribe to these message
is there any way to restrict the access of the devices to the message published by the trucks? in another words, lets assume truck1 publishes the following messages (truck1_msg1, truck1_msg2, truck1_msg) I want App1 able to subscribe and listen to the messages from truck1 only and never be able to subscribe and see any other messages published by other trucks. is it possible? would you please let me how can I do it?
note: all the trucks and the Apps are connected to the same broker, and lets assume it is Mosquitto
Most MQTT brokers support topic level ACLs for a given user so assuming each truck publishes messages to a distinct topic (or topic prefix as ACLs tend to support wild cards) and each truck and app has it's own user you should be able to arrange any segregation of access you need.
Each broker have different mechanisms for managing these ACLs, for example here are the details for mosquitto.
The documentation for mosquitto's ACL format can be found in it's man page here: https://mosquitto.org/man/mosquitto-conf-5.html
You add an ACL file to the mosquitto.conf with the acl_file option:
acl_file /path/to/acl/file
The ACL file format looks like this:
user <username>
topic [read|write|readwrite] <topic>
You can have multiple topic lines per user.
Details of how to enable user authentication is also in the man page.