[Nest] nest에서 MicroService 세팅하기(mqtt 세팅하기)
공식문서를 참고하면 더욱 이해를 빠르게 하실 수 있습니다.
nest서버를 http로 활용하는데 mqtt 를 활용하는 mqtt서버를 추가 할 때 mqtt 통신을 설정하는 방법입니다.
0. mqtt 서버 세팅
docker로 손쉽게 mqtt 서버를 세팅할 수 있습니다. mosquitto를 docker로 깔아서 로컬로 돌리면서 테스트를 해볼 수 있는데요.
docker run -it --name mosquitto -p 1883:1883 eclipse-mosquitto
docker로 eclipse-mosquitto의 이미지를 받아온 후
docker start mosquitto 를 실행하면 mosequitto가 1883포트를 열고 돌아갑니다.
1. nest에서 mqtt 세팅
//마이크로서비스
npm install @nestjs/microservices
//mqtt서버
npm install mqtt
먼저 nest에서 mqtt의 서비스를 사용하기 위해서는 microservice를 사용해야 합니다. microservice로 redis, kafka등 다양한 서브 서버를 활용할 수 있습니다.
main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
declare const module: any;
async function bootstrap() {
// 1. http서버로 사용
const app = await NestFactory.create(AppModule);
// 2. mqtt서버로 사용
const mqttApp = await NestFactory.createMicroservice<MicroserviceOptions>(
AppModule,
{
transport: Transport.MQTT,
// options: { host: 'localhost', port: 1833, url: 'mqtt://localhost:1883' },
options: { url: 'mqtt://localhost:1883' },
},
);
await mqttApp.listen();
await app.listen(port);
}
bootstrap();
main.ts파일에 createMicroservice를 활용해서 mqtt서버를 생성해줍니다. createMicroservice(root Module, options)로 구성되어 있습니다.
mqttApp은 mqtt서버에 접속해서 메시지를 일고 전달하는 역할을 하게 됩니다.
이제 mqtt통신을 관리하는 모듈을 만들것입니다.
루트 파일에 mqtt.controller, mqtt.module, mqtt.service를 만들어줍니다.
mqtt.module.ts
import { ClientsModule, Transport } from '@nestjs/microservices';
import { Module } from '@nestjs/common';
import { MqttController } from './mqtt.controller';
import { MqttService } from './mqtt.service';
const clients = ClientsModule.register([
{
name: 'MQTT_SERVICE', //* MQTT_SERVICE : 의존성 이름
transport: Transport.MQTT,
options: {
host: 'localhost',
port: 1883,
},
},
]);
@Module({
imports: [clients],
controllers: [MqttController],
providers: [MqttService],
exports: [clients], // 다른 모듈에서 쓸 수 있게 출력
})
export class MqttModule {
constructor() {}
}
먼저 mqttModule을 만들어줍니다. 정확히는 client의 모듈을 만드는데 client는 mqtt 통신을 하는 client를 생성합니다.
mqtt.controller.ts
import { Controller, Inject } from '@nestjs/common';
import { MessagePattern, Payload, ClientProxy } from '@nestjs/microservices';
import { take } from 'rxjs';
@Controller()
export class MqttController {
constructor(@Inject('MQTT_SERVICE') private client: ClientProxy) {
//* MY_MQTT_SERVICE : 의존성 이름
setInterval(() => {
//5초마다 메시지를 발송하게 하였습니다.
const data = {
number: Math.random(),
text: MqttController.name,
time: `진행${new Date().getTime()}`,
};
this.client.send('Korean', data).pipe(take(100)).subscribe();
}, 5000);
}
@MessagePattern('World') //구독하는 주제1
getAll(@Payload() data) {
console.log(data);
}
@MessagePattern('American') //구독하는 주제2
getUnique(@Payload() data) {
console.log(data);
}
}
mqtt.contoller에서는 위에서 만든 mqttClinet를 주입받습니다.
@MessagePattern으로 topic의 구독설정을 합니다.
@Payload로 데이터를 받습니다.
mqtt.service.ts
import { Injectable } from '@nestjs/common';
@Injectable()
export class MqttService {
getHello(): string {
return 'Hello Mqtt!';
}
}
controller에서 비지니스 로직이 필요하다면 service에다 입력받고 controller에 주입시켜서 사용할 수 있습니다.
2. http Controller에서 사용하기
http통신으로 사용하던 AppController에서 mqtt 통신을 사용해보겠습니다.
import { Controller, Get, Inject } from '@nestjs/common';
import { AppService } from './app.service';
import { ClientProxy } from '@nestjs/microservices';
import { take } from 'rxjs';
@Controller()
export class AppController {
constructor(
@Inject('MQTT_SERVICE') private client: ClientProxy,
private readonly appService: AppService,
) {}
@Get()
async getHello(): Promise<string> {
await this.client
.send('test', { data: 'test', time: new Date().toISOString() })
.pipe(take(1))
.subscribe();
return this.appService.getHello();
}
}
생산자에 Mqtt client를 주입 받습니다.
GET / 요청 시 clinet에 test란 데이터를 보내게 됩니다.
get / 에 요청을 보냈고 200 상태를 받았습니다.
mqtt explorer로 test 토픽을 보았을 때 원하는 데이터가 들어온 것을 확인할 수 있습니다.
참고
Nestjs 프레임워크 서버(microservices, mqtt) -17 (tistory.com)
MQTT - Microservices | NestJS - A progressive Node.js framework