Overview:
This pull request introduces a new feature to the Publisher class, allowing it to publish individual key-value pairs from a JSON object to separate MQTT topics. The original functionality of publishing the entire JSON object to a single topic is preserved, while the new feature adds the ability to automatically distribute the data across multiple topics.
Changes Introduced:
Recursive Topic Publishing: The publish method now includes a recursive function that iterates through a JSON object, publishing each key-value pair to a corresponding MQTT topic.
Maintained Backward Compatibility: The class maintains the original behavior of publishing the entire JSON object as a single message to the specified topic.
src/publish.ts
import { AsyncMqttClient, connectAsync } from "async-mqtt";
/**
* The Publisher class is responsible for publishing messages to an MQTT broker.
* It supports both publishing a complete JSON message to a single topic
* and recursively splitting the JSON into individual topics for detailed data publishing.
*/
export class Publisher {
private client: AsyncMqttClient | undefined;
/**
* Constructs a new Publisher instance.
*
* @param url - The URL of the MQTT broker.
* @param retain - An optional flag indicating whether the published messages should be retained by the broker.
* @param clientId - An optional client ID to identify the connection. If not provided, the MQTT broker may assign one.
* @param username - An optional username for broker authentication.
* @param password - An optional password for broker authentication.
*/
constructor(
private readonly url: string,
private readonly retain?: boolean,
private readonly clientId?: string,
private readonly username?: string,
private readonly password?: string,
) {}
/**
* Ensures an active connection to the MQTT broker.
*
* @returns An instance of AsyncMqttClient representing the active connection.
*/
private async getClient() {
if (this.client && this.client.connected) {
return this.client;
}
await this.client?.end(); // Ends any existing connection if present.
this.client = await connectAsync(this.url, {
clientId: this.clientId,
username: this.username,
password: this.password,
});
return this.client;
}
/**
* Recursively publishes each key-value pair of a JSON object to separate MQTT topics.
*
* @param baseTopic - The base topic under which all subtopics will be published.
* @param data - The data to be published, can be an object or a primitive value.
*/
private async publishRecursively(baseTopic: string, data: any) {
if (typeof data === 'object' && data !== null) {
// If the data is an object, iterate over its keys and call this method recursively.
for (const key in data) {
if (data.hasOwnProperty(key)) {
await this.publishRecursively(`${baseTopic}/${key}`, data[key]);
}
}
} else {
// If the data is a primitive value, publish it to the appropriate topic.
await (await this.getClient()).publish(baseTopic, String(data), { retain: this.retain });
}
}
/**
* Publishes a message to a specified MQTT topic.
* This method handles both sending the entire JSON message to a single topic
* and splitting the JSON into multiple topics for granular data distribution.
*
* @param topic - The MQTT topic to which the message will be published.
* @param message - The message to be published. It can be a JSON object or any other data type.
*/
async publish(topic: string, message: any) {
// Publish the entire JSON object as a single message to the given topic.
await (await this.getClient()).publish(topic, JSON.stringify(message), { retain: this.retain });
// Recursively publish each element of the JSON object to its own topic.
await this.publishRecursively(topic, message);
}
}
Overview: This pull request introduces a new feature to the Publisher class, allowing it to publish individual key-value pairs from a JSON object to separate MQTT topics. The original functionality of publishing the entire JSON object to a single topic is preserved, while the new feature adds the ability to automatically distribute the data across multiple topics.
Changes Introduced:
Recursive Topic Publishing: The publish method now includes a recursive function that iterates through a JSON object, publishing each key-value pair to a corresponding MQTT topic.
Maintained Backward Compatibility: The class maintains the original behavior of publishing the entire JSON object as a single message to the specified topic.
src/publish.ts