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
我使用 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' classimport { 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