Nestjs ClientMqtt.emit 将模式和数据都发布到代理,而不仅仅是数据

Nestjs ClientMqtt.emit publish both pattern and data to broker rather than only data

我使用 Nestjs 将数据发布到 Mqtt Broker,但它同时发送模式和数据,而不仅仅是这样的数据:

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

app.module.ts 中,我像这样导入 MQTT 客户端:

@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],
})

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';
    }
}

我还发现在ClientMqtt代理source code中,方法publish是发布所有partialPacket也就是JSON{模式, data} 而不仅仅是 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),
        );
      });
      ...
  }

那么如果我只想使用ClientMqtt代理,而只是发布数据包的数据字段,我该怎么办?

我遇到了和你一样的问题,我用的是nest-mqtt

app.module.ts

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 {}

app.service.ts

/**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);
  }

}

您可以使用序列化程序更改发送到 MQTT 代理的消息的结构。为此,您需要在 ClientsModule 注册中包含 'serializer' 属性:

@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],
})

通过此更改,您需要在实现方法 'serialize':

的其他文件中创建 'OutboundResponseSerializer' class
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;
    }
}

有了这个变化,您的消息只包含数据信息。

您可以在 link 的 'Implementing Serializers and Deserializers' 部分找到更多相关信息:https://dev.to/nestjs/integrate-nestjs-with-external-services-using-microservice-transporters-part-3-4m20