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

Angular2 ERROR: Unhandled Promise Rejection: Cannot find a matching route:

I'm facing an issue with my Angular2 application while utilizing the router.navigateByUrl method. Within my component, there is a function named goToRoute, structured as follows: router.goToRoute(route:string, event?:Event):void { if (event) ...

Referring to a component type causes a cycle of dependencies

I have a unique situation where I am using a single service to open multiple dialogs, some of which can trigger other dialogs through the same service. The dynamic dialog service from PrimeNg is being used to open a dialog component by Type<any>. Ho ...

How can I exhibit JSON object information in an Angular 2 dropdown menu?

CSS <!-- Custom CSS Styling for Dropdown --> <div class="row no-overflow"> <div class="col-md-1 window-pad-height no-overflow"> <m ...

"Enhance user experience with Angular Material: Popup Windows that preserve functionality in the original window while staying vibrant and accessible

Exploring Angular Material Dialog and other Popup Window Components for a project. Making progress but facing some challenges. Here are the requirements: a) The original screen should not be grayed out, b) Users should be able to interact with the windo ...

Issue with React TypeScript: Only the first state update takes effect, despite multiple updates being made

Check out this sandbox I created here. When you leave any of the form inputs blank, I should be seeing 3 errors but instead, I only get one. Can anyone explain why this is happening? import React, { ChangeEvent, useState } from 'react'; import { ...

Seeking a breakdown of fundamental Typescript/Javascript and RxJs code

Trying to make sense of rxjs has been a challenge for me, especially when looking at these specific lines of code: const dispatcher = fn => (...args) => appState.next(fn(...args)); const actionX = dispatcher(data =>({type: 'X', data})); ...

What is the step-by-step guide for implementing an access limiter on an interface

When attempting to modify the access level on an interface in Typescript, I encountered an error stating 'cannot appear in type member.' After removing the access limiter on the interface and implementing it, I tried changing the access limiter o ...

``Can you provide guidance on excluding matching values from a dictionary object in a Angular project?

I've developed a function that takes a dictionary object and matches an array as shown below: const dict = { CheckAStatus: "PASS", CheckAHeading: "", CheckADetail: "", CheckBStatus: "FAIL", CheckBHeading: "Heading1", CheckCStatus: "FAIL", ...

Error: Unable to access 'subscribe' property of empty object in Angular Unit Test

After making updates to an Angular component, I encountered issues with broken unit tests. All test specs are failing, leading me to believe that the problem lies in the initialization within the beforeEach calls. Despite extensive research, I have been un ...

Eliminating empty elements from arrays that are nested inside other arrays

I am facing a challenge with the array structure below: const obj = [ { "description": "PCS ", "children": [ null, { "name": "Son", ...

Why am I encountering a 400 error with my mutation in Apollo Client, when I have no issues running it in Playground?

After successfully testing a mutation in the playground, I attempted to implement it in my Apollo client on React. However, I encountered an error message stating: Unhandled Rejection (Error): Network error: Response not successful: Received status code 40 ...

Certain sections within a Formik form are failing to update as intended

I have successfully implemented a custom TextField wrapper for Material-UI fields, but I am facing an issue with native Material UI fields not updating the form data upon submission. Below is the relevant code snippet along with a link to a code sandbox d ...

Exploring the Integration of Two Independent Microservices via RESTful API for Data Exchange

Is there a way to establish a connection between two distinct APIs in different programming languages? Specifically, I have an application built in node.js with MongoDB and another one in Python with MySQL. I'm facing the challenge of establishing a 1 ...

The code encountered an error with message TS2345 stating that the argument type '(a: Test, b: Test) => boolean | 1' cannot be assigned to a parameter type of '(a: Test, b: Test) => number'

Apologies for the lengthy subject, but I am having trouble understanding the response. Here is my code snippet: this.rezerwacjeFilteredByseaarchInput.sort(function (a, b) { if (a[5]===null) { // console.log(a[5]); return 1; } ...

Creating a canvas that adjusts proportionally to different screen sizes

Currently, I am developing a pong game using Angular for the frontend, and the game is displayed inside an HTML canvas. Check out the HTML code below: <div style="height: 70%; width: 70%;" align="center"> <canvas id=&q ...

Validator returns undefined when expressing invalid data

Having an issue with validation, here is the code snippet: routes.js var express = require('express'); var router = express.Router(); var hello_controller = require('../api/controllers/helloController'); var { validationRules, validat ...

Struggling to figure out webhooks with Stripe

I have encountered a strange issue while using Stripe webhooks to process payments on my website. When I set the currency to USD, it prompts me to provide an address outside of India, which is expected. However, when I change the currency to INR, the addre ...

Injecting configurable middleware dependencies in Nest.js allows for dynamic customization of middleware

While many tutorials demonstrate how to inject providers into dynamic modules, most of them only focus on services and not middleware. The challenge arises when attempting to create reusable middleware that also requires injected providers. For instance, ...

The issue arises when using Angular Material as it seems that passing a data object to a matdialog dialog

After reviewing multiple posts and carefully examining the process of passing data from an Angular Component to MatDialog, I am facing an issue where 'undefined' is being returned when the dialog loads. Below is the code snippet I have been work ...

Injecting services with an abstract class is a common practice in Angular library modules

In my development workflow, I have established an Angular Component Library that I deploy using NPM (via Nexus) to various similar projects. This library includes a PageComponent, which contains a FooterComponent and a NavbarComponent. Within the NavbarCom ...