Express에서 사용했던 web Socket기능을 Nest에서도 사용해 보았다.
$ npm i --save @nestjs/websockets @nestjs/platform-socket.io socket.id
WebSocket의 대부분은 Gateway를 사용한다
게이트웨이 클래스를 만든다.
nest g ga message //게이트웨이 , Injectable클래스다.
nest g mo message //모듈
@SubscribeMessage()를 이용하면 클라이언트쪽에서 이벤트가 발생 하였을때 메소드를 실행할 수 있다. (express의 socket.on과 비슷한기능?)
@WebSocketGateway(/*{namespace:"네임스페이스를 설정해줄수 있다"}*/)
@SubscribeMessage('firstJoin')
userList(@MessageBody() nick:string, @ConnectedSocket() socket:Socket): void {
let usernick = nick;
}
OnGatewayInit :afterInit을 강제로함 (생성자 다음으로 실행된다)
OnGatewayConnection Forces to implement the handleConnection(): handleConnection()을 강제함 (커넥션이 되면작동)
OnGatewayDisconnect Forces to implement the handleDisconnect() handleDisconnect()를 강제함 (커넥션이 해제되면 작동)
@WebSocketGateway(/*{namespace:"네임스페이스를 설정해줄수 있다"}*/)
export class MessageGateway
implements OnGatewayConnection, OnGatewayDisconnect
{
private userList = [];
private usernick: string;
handleConnection(@ConnectedSocket() socket: Socket) {
console.log(`${socket.id} 접속`);
}
handleDisconnect(@ConnectedSocket() socket: Socket) {
console.log(`${socket.id} 접속해제`);
this.userList.forEach((e, i) => {
if (e[0] === this.usernick) {
this.userList.splice(i, 1);
}
});
socket.emit('userUpdate', this.userList);
}
@SubscribeMessage('firstJoin')
userListSet(
@MessageBody() nick: string,
@ConnectedSocket() socket: Socket,
): void {
this.usernick = nick;
const check = this.userList.some((e) => e[0] === nick); //닉이 중복이있을시 true 리턴
if (!check) {
this.userList.push([nick, socket.id]);
}
socket.emit('userUpdate', this.userList); //유저리스트 최신화
}
@SubscribeMessage('message')
sendMessage(
@MessageBody() data: { id: string; nick: string; message: string },
@ConnectedSocket() socket: Socket,
): void {
socket.to(data.id).emit('letter', data); //유저리스트 최신화
}
}