I am using eclipse paho java client to connect to mqtt broker.
Have written a subscriber client implementing MqttCallbackExtended.
I am getting connectionLost() callback.
But how do I get to know that which broker lost the connection.
I have specified multiple uri's via setServerURIs() api of MqttConnectOptions.
If you have specified multiple brokers, they all should be part of the same cluster offering the same topic space.
This means you shouldn't need to care from the client side which broker you were connected to as the client will just move to the next in the list when it tries to reconnect.
But if you really need to know, then you can always log the URI when the connection is created using the information from the connectionComplete() callback on the MqttCallbackExtended class
Related
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 have read that the overhead is low. What does it really mean when compared to HTTP? Does it not use the ip address of the server to which a client tries to connect to? If not, how does a client connect to a server?
Low overhead means that for a given size of messages there is very little extra information sent. It has nothing to do with broker discovery.
E.g. for a HTTP message there us a relatively large amount of HTTP Headers sent before any of the message is transmitted.
The client will connect to the broker via it's IP address. This can either be known in advance, looked up from a host name via DNS or looked up via a TXT record in the DNS for a given domain. You can see examples of broker discovery on the mqtt.org site here
I have a server on the cloud that receives MQTT messages and I'm running the Node-RED on a Raspberry pi on my localhost...
With the Raspberry, I'm receiving data from different devices using the MQTT protocol. And until here, it works great! The problem is when I try to receive messages from the MQTT broker that's running locally (on the Raspberry) and then send these messages to other MQTT broker that's running on another server. Something like this image:
When I try to use two different brokers with the Node-RED, it automatically updates all other nodes to the last broker that I had configured. So, is it possible to open a connection with two different MQTT Brokers when I'm using the Node-RED?
In the MQTT node edit dialog, the 'Server' field is a select box. It lists all of the broker configurations you have in your flow.
To add a connection to a different broker, select the 'Add new mqtt-broker...' option then click the button next to the select box.
That adds a new connection configuration rather than edit the one already being used by your existing nodes.
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.
I am looking for a solution to poll messages from MQTT broker. I will describe the solution briefly here.
We have a Spring based Controller class which exposes REST APIs to handle certain vehicle related diagnostics data. Through one of these API-s Notify3P() I create a MQTT java client and publish messages based on some input data to the MQTT broker on a given topic. My requirement is to notify a third-party system every time the client publishes a message on MQTT.
The 3P system is going to pick up the message from MQTT once it receives the notification. It then needs to get the message from the MQTT broker through a getMessage() REST API (which we need to expose on the above controller class). The getMessage() API needs to poll MQTT for the messages that have already been published and hand it to the 3P system. The 3P system would then do some processing and send back a response to our system through another REST API postMessage() exposed on our controller class. The postMessage() should post the message on the response topic on MQTT. I need another REST API checkResponse() which then polls the response topic of MQTT and send back the response to the client.
What I have done so far: On application start up I have a start up bean which listens to MQTT request and response topics. Now I publish data to request topic using the REST API Notify3P(). I have attached a callback with the startup bean which gets the message. The problem comes when the 3P needs to call my controller to poll message from MQTT.
I am not clear how to hold back messages on MQTT and consume it on demand. Is there a mechanism to do it in MQTT? Also once the 3P system post messages on the response then again how do I poll the response topic to pick up the response from MQTT and send to clients of my Controller?
I hope the problem description makes sense. If there is any solution from anyone please post it. Any sample code would of great help.
Thanks in advance!!
You may have got the idea of MQTT a bit confused. One of the key points is that there is no polling.
You subscribe to your response topic and publish to the request topic. As soon as a response is available you will be sent it by the broker. You can't hold back messages.
It sounds like your controller also needs to talk MQTT. If it is subscribed to the response topic from the start then it will receive the messages and you can do with them what you will, no need for polling.
To achieve exactly what you want, where the third party notifies the controller to read messages from MQTT then the controller would need to be able to use MQTT anyway. At that point you might as well do it "properly". If you don't want to integrate MQTT into your controller, then you can't do what you describe and you will have to come up with another means of communicating between the two components.
Summary - get your controller to talk MQTT if you can.