Closed botsbuzz closed 4 years ago
Use the parameters responseTopic
and optionally correlationData
in the publish function,
I haven't used this feature yet but I guess the subscriber has to check if a responseTopic was set.
Here is a great article with more information: https://www.hivemq.com/blog/mqtt5-essentials-part9-request-response-pattern/
Thank you so much for your help!
Although the issue is closed, I would like to give an example for anyone who needs this since this cost me quite some time to figure this out.
Make sure your broker supports MQTT v5. Initialize both publisher and subscriber with these client options:
this.mqttClient = mqtt.connect(this.mqttEndpoint, {
protocolVersion: 5,
properties: {
requestResponseInformation: true,
requestProblemInformation: true,
}
});
Think of a way to correlate request and response, I used the uuid package:
let corId = uuidv4();
// You can use this to get the response back to your invoking method
// This should be clear to you when reading until the end
let res = new Promise((resolve, reject) => {
this.ee.once(corId, resolve)
});
If you publish a message, add properties responseTopic
and correlationData
to it, at the time of writing these are not yet in the type-definitions so when using TypeScript you need to use // @ts-ignore
.
this.getMqttClient().publish(topic, JSON.stringify(data), {
// @ts-ignore
properties: {
responseTopic: 'your/response/topic',
correlationData: corId
},
});
Now, the subscriber should get those two properties in the packet
parameter:
this.mqttClient.on('message', (topic, message, packet) => {
if (topic.startsWith(this.topicPrefix)) {
try {
// @ts-ignore
let responseTopic = packet.properties.responseTopic;
let correlationData = packet.properties.correlationData;
}
catch (e) {
...
}
}
});
Use these in your response as well:
this.mqttClient.publish(responseTopic, JSON.stringify(message), {
// @ts-ignore
properties: {
correlationData: packet.properties.correlationData
}
});
This is probably not a very beautiful solution to solve the last piece of the puzzle, but I could not think of another way. To correlate the response at the requesters side, I used the node.js EventEmitter
which broadcoasts an event with the correlationData
this.mqttClient.on('message', (topic, payload, packet) => {
if (topic === 'your/response/topic') {
this.ee.emit( packet.properties.correlationData.toString(), payload.toString() )
}
});
// You can use this to get the response back to your invoking method
let res = new Promise((resolve, reject) => {
this.ee.once(corId, resolve)
});
Thank you @dsbaars. This was quite a help.
Anyone could help with this?