Contents
WebsocketWebsocket
- 웹소켓은 TCP통신 방식으로 서버와 클라이언트 사이에 데이터를 주고 받을 수 있는 기술이다.
- REST API와 다르게 서버와 브라우저간 연결이 유지된채로 양방향 통신을 할 수 있음
- Websocket vs Socket.io
- 설치
$ npm i --save @nestjs/websockets @nestjs/platform-socket.io
Server side example
import { SubscribeMessage, WebSocketGateway, OnGatewayInit, OnGatewayConnection,OnGatewayDisconnect, WebSocketServer } from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';
import { MessageBody } from '@nestjs/websockets';
@WebSocketGateway({ cors: true })
export class EventsGateway
implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect
{
constructor() {}
@WebSocketServer() server: Server;
private logger: Logger = new Logger('EventsGateway');
@SubscribeMessage('message')
onNewMessage(@MessageBody() data: string): string {
console.log("onNewMessage: ", data);
return data;
}
afterInit(server: Server) {
this.logger.log('웹소켓 서버 초기화 ✅');
}
handleConnection(client: Socket, ...args: any[]) {
this.logger.log(`Client Connected : ${client.id}`);
}
handleDisconnect(client: Socket) {
this.logger.log(`Client Disconnected : ${client.id}`);
}
}
@WebSocketServer
- 어노테이션을 통해 WebSocketServer 이라는 것을 명시
server: Server;
의 server은socket.io
의 server 사용
@SubscribeMessage
- 어노테이션을 통해 해당 소켓의 이벤트(토픽)으로 웹 소켓 데이터 전달
OnGatewayInit.afterInit
: Gateway 진입 시 작업
OnGatewayConnection.handleConnection
: 소켓 연결 성공 시 작업
OnGatewayDisconnect.handleDisconnect
: 소켓 연결 해제 시 작업
Client (nextjs)
- webSocketContext.tsx
import { createContext } from 'react';
import { io, Socket } from 'socket.io-client';
export const socket = io('http://localhost:8080');
export const WebsocketContext = createContext<Socket>(socket);
export const WebsocketProvider = WebsocketContext.Provider;
createContext
: 일일히 props를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 제공할 수 있다.WebsocketContext.Provider
: context를 구독하는 컴포넌트들에게 context의 변화를 알린다. value props를 받아서 이 값을 하위 컴포넌트들에게 전달하는데, value가 바뀔 때마다 다시 렌더링된다.
// page.tsx
const Home = () => {
return (
<WebsocketProvider value={socket}> // value의 변경마다 다시 랜더링
<Websocket />
</WebsocketProvider>
);
};
- websocket.tsx
socket.on("connect", () => {
console.log("Connected!");
});
socket.on("disconnect", () => {
console.log("Disconnected!");
socket.disconnect();
});
socket.on("onMessage", (inputMessage: Message) => { // 메세지 수신
setNewMessage([
...newMessage,
new Message(inputMessage.writer, inputMessage.message),
]);
});
// 메세지 전송 버튼
const onSubmit = () => {
if (value == "" || socket.id === undefined) {
return;
}
setMe(socket.id.substring(0, 8));
socket.emit("newMessage", { // 메세지 전송
writer: socket.id.substring(0, 8),
message: value,
});
setValue("");
};
Share article