The Nestjs ClientMqtt now has the capability to publish both pattern and data to the broker, as opposed to just sending

I am currently utilizing Nestjs for sending data to a Mqtt Broker. However, I am facing an issue where it sends both the pattern and data instead of just the data in this format:

{
    "pattern": "test/test",
    "data": "Data"
}

Within the app.module.ts, I have imported the MQTT Client as follows:

@Module({
    imports: [
        ClientsModule.register([
            {
                name: 'MQTT_CLIENT',
                transport: Transport.MQTT,
                options: {
                    url: 'tcp://abc.abc.com',
                    username: 'name',
                    password: 'psswrd',
                    port: 1883,
                },
            },
        ]),
    ],
    controllers: [AppController],
    providers: [AppService],
})

and in the app.controller.ts:

@Controller()
export class AppController {
    constructor(@Inject('MQTT_CLIENT') private client: ClientMqtt) {}

    async onApplicationBootstrap() {
        await this.client.connect();
    }

    @Get()
    getHello(): string {
        this.client.emit('test/test', 'Data')
        return 'Done';
    }
}

Upon further investigation into the ClientMqtt proxy source code, I discovered that the method publish is designed to publish the entire partialPacket which includes the JSON {pattern, data} rather than solely packet.data

protected publish(
    partialPacket: ReadPacket,
    callback: (packet: WritePacket) => any,
  ): Function {
    try {
      const packet = this.assignPacketId(partialPacket);
      const pattern = this.normalizePattern(partialPacket.pattern);

      ...
        this.mqttClient.publish(
          this.getAckPatternName(pattern),
          JSON.stringify(packet),
        );
      });
      ...
  }

If my intention is to utilize the ClientMqtt proxy but only publish the data field of the packet, what approach should I take?

Answer №1

To modify the structure of messages sent to an MQTT broker, utilize serializers. To do this, include the 'serializer' attribute in the ClientsModule registration:

@Module({
    imports: [
        ClientsModule.register([
            {
                name: 'MQTT_CLIENT',
                transport: Transport.MQTT,
                options: {
                    url: 'tcp://abc.abc.com',
                    username: 'name',
                    password: 'psswrd',
                    port: 1883,
                    serializer: new OutboundResponseSerializer()
                },
            },
        ]),
    ],
    controllers: [AppController],
    providers: [AppService],
})

After making this change, create a separate file for the 'OutboundResponseSerializer' class that implements the 'serialize' method:

import { Serializer, OutgoingResponse } from '@nestjs/microservices';
import { Logger } from '@nestjs/common';

export class OutboundResponseSerializer implements Serializer {

    private readonly logger = new Logger('OutboundResponseIdentitySerializer');

    serialize(value: any): OutgoingResponse {
      this.logger.debug(`-->> Serializing outbound response: \n${JSON.stringify(value)}`);
      return value.data;
    }
}

By implementing these changes, your messages will only include the data information.

For more details on implementing Serializers and Deserializers, visit: https://dev.to/nestjs/integrate-nestjs-with-external-services-using-microservice-transporters-part-3-4m20

Answer №2

Encountering a similar issue, I turned to nest-mqtt for assistance.

Answer №3

NestJS Configuration Files

import { Module } from '@nestjs/common';
import { MqttModule } from 'nest-mqtt';
import { AppService } from './app.service';
import { AppController } from './app.controller';

@Module({
  imports: [
    MqttModule.forRoot({
      host: '192.168.0.73',
      port: 1883,
      clientId: 'clientId',
      username: 'your username',
      password: 'your password',
      clean: false ,
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Mqtt Service Implementation

/**nest-mqtt */
import { MqttService, Payload, Subscribe } from 'nest-mqtt';


/**nestjs common */
import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common';

@Injectable()
export class AppService {

  constructor(
    @Inject(MqttService) private readonly mqttService: MqttService,
  ) {}


  /**Subscription information */
  @Subscribe('your subject')
  async handleGetDeviceData(@Payload() payload: ISubjectSendData) {
   // Processing received messages
  }

  /**publish payload */
  async handelSendMsgToDevice(device: string, payload: any) {
    this.mqttService.publish(device, payload);
  }

}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is the Scope Staying Static in AngularJS 1.4 when Input Text Changes and Two-Way Binding is Enabled?

Encountering a strange issue with AngularJS 1.4 (TypeScript). The problem lies within the controller where a variable is set and displayed in an input text box. Oddly, when attempting to edit the value in this text box and clicking on a button, the variabl ...

Can you explain the purpose of FunctionConstructor in typeScript?

As I delved into the Typescript Ecmascript source code, I stumbled upon this intriguing snippet: interface FunctionConstructor { /** * Creates a new function. * @param args A list of arguments the function accepts. */ new(...args: st ...

Error encountered while fetching client credentials in Next-Auth Credential-Provider [next-auth]

Exploring the combination of nextjs and next-auth for authentication using a credential provider has been intriguing. However, I've encountered an issue when attempting to access a protected route while logged in: [next-auth][error][client_fetch_error ...

the process of accessing information from a service in an Angular Typescript file

After making a POST request using Angular's HTTP client, the response data can be accessed within the service. However, is there a way to access this data in the app.component.ts file? I am able to retrieve the response data within the service, but I ...

Ways to toggle checkboxes to show or hide their child items and subitems

I'm working on creating a straightforward menu that allows users to click on a parent checkbox to expand or collapse its children. The challenge I'm facing is how to make the parent checkboxes expand while hiding the children items within them wh ...

Parsing error encountered while trying to handle an unexpected token at line 214, character 33. It appears that an appropriate loader is missing to process this particular file type

I've been developing a Typescript React project for the past few months without any issues. However, things took a turn yesterday when I decided to run npm audit fix and npm audit fix --force in order to address some security concerns that appeared ou ...

The wss websocket connection is experiencing issues in Firefox 89 when attempting to connect on localhost

For some reason, the websocket wss connection is not working in Firefox 89 when trying to connect on localhost. Interestingly, I can successfully establish a connection using my to connect to from the production server. However, when attempting to init ...

Choosing between Angular's Observable and Subject as a DataSourceWhen it comes

I am currently working on an Angular 7 application that utilizes Mat Tables to retrieve data from an API. I have implemented dynamic pagination values, where the pageSizeOptions value changes based on a dropdown selection when loading the grid. By default, ...

Customizing MUI DataGrid: Implementing unique event listeners like `rowDragStart` or `rowDragOver`

Looking to enhance MUI DataGrid's functionality by adding custom event listeners like rowDragStart or rowDragOver? Unfortunately, DataGrid doesn't have predefined props for these specific events. To learn more, check out the official documentati ...

Methods for organizing consecutive elements within an array in Javascript/Typescript

Let's explore this collection of objects: [ { key1: "AAA", key2: "BBB" }, { key1: "BBB", key2: "CCC" }, { key1: "CCC", key2: "DD ...

Combining two streams in RxJS and terminating the merged stream when a particular input is triggered

I am currently developing an Angular application and working on implementing a system where an NGRX effect will make requests to a service. This service will essentially perform two tasks: Firstly, it will check the local cache (sqlite) for the requested ...

What is the best way to add JSX to the DOM using React?

Looking to make an addition to my DOM. let parent = document.getElementById("TabContainer"); let settings = <Box id="test"> <GlobalSettings activeTab={"test"}></GlobalSettings> </Box> ...

What is causing the reluctance of my Angular test to accept my custom form validation function?

I'm currently facing an issue with testing an angular component called "FooComponent" using Karma/Jasmine. Snippet of code from foo.component.spec.ts file: describe('FooComponent', () => { let component: FooComponent let fixture ...

Display a separate component within a primary component upon clicking a button

Looking to display data from a placeholder module upon component click. As a beginner with React, my attempts have been unsuccessful so far. I have a component that lists some information for each element in the module as a list, and I would like to be ab ...

Upgrade to Angular 12: TypeScript is now an essential requirement for the Angular Compiler

Recently, I made sure to update my project to the latest Angular version. After running "ng update", I received a confirmation that everything was already up to date, indicating that all required packages had been successfully updated in the last step of t ...

Error Message: The Query<DocumentData> type cannot be assigned to the DocumentReference<DocumentData> parameter

Currently, I am attempting to execute a query against Firestore data. Here is my code snippet: import { collection, getDoc, query, where } from "firebase/firestore"; import { db } from "../../utils/firebaseConfig"; const getQuery = a ...

Parent observable method encountering an error while grouping multiple HTTP calls in Angular

I am facing an issue with managing multiple http calls and handling errors that may occur during their execution. I want to be able to identify which calls have failed so that I can retry them using a different method. However, without visibility at the co ...

An obstacle encountered when implementing feature module services in a controller for a Nest JS microservice

Recently, I developed a feature module named "user" which includes a controller, model, and services to interact with my postgres database. Despite setting up everything correctly, I encountered an error when trying to call userService from the feature mod ...

What is the method to access the information within the observer?

When I receive the data from the observer in the console, here is what I see: https://i.stack.imgur.com/dVzwu.png However, I am only interested in extracting this specific data from each item on the list: https://i.stack.imgur.com/g8oHL.png To extract ...

Issue with Nestjs validate function in conjunction with JWT authentication

I am currently implementing jwt in nest by following this guide Everything seems to be working fine, except for the validate function in jwt.strategy.ts This is the code from my jwt.strategy.ts file: import { Injectable, UnauthorizedException } from &ap ...