채팅을 만들려면 채팅방도 만들어야 하고, 접속한 유저 모두에게 메시지를 발송하는 브로드캐스팅 기능도 필요하고 여러 기능들이 필요하다.
socket.io는 웹소켓을 기반으로 서버와 클라이언트의 양방향 통신을 지원하는 라이브러리이다.
작업 순서
- 프로젝트 생성 및 패키지 설치
- 정적 파일 서비스를 위한 main.ts 설정
- socket.io 서버 구동을 위한 게이트웨이 만들기
- 클라이언트 측 코드 작성
- 테스트
1.패키지 설치하기
@nestjs/websockets : 클라이언트와 서버를 연결하고 양방향 통신 또는 데이터 전송이 가능하게 해주는 패키지
@nestjs/platform-socket.io : 웹소켓의 성능향상이나, 실시간 데이터 동기화 같은 웹소켓 프로토콜 기반의 프로그램 작성 시 필수인 패키지
2. 정적 파일 서비스 설정
NestJS에서는 정적 파일을 불러오는 기능을 제공한다.
// 반환형을 NestExpressApplication형으로 지정해 정적 메서드를 사용한다.
const app = await NestFactory.create<NestExpressApplication>(AppModule);
// useStaticAssets : 정적 파일의 경로를 지정
app.useStaticAssets(join(__dirname, '..', 'static'));
3. 서버 측 작업을 위한 게이트웨이 만들기
NestJS에서는 웹소켓을 사용한 통신을 받아주는 클래스를 게이트웨이라한다.
게이트웨이를 만드는 방법은 @WebSocketGateway() 데코레이터를 클래스에 붙이면 된다.
@WebSocketServer() : 실제 WebSocket 서버 인스턴스를 참조하게 되서 클라이언트에 메시지 전송, 연결, 관리같은 WebSocket 서버를 제어할 수 있다.
@WebSocketGateway() //게이트웨이 설정
export class ChatGateway{
@WebSocketServer() server: Server; // 웹소켓 인스턴스 생성
@SubscribeMessage('message') //해당 이벤트 구독
handleMessage(socket: Socket, data: any): void {
this.server.emit('message', `client-${socket.id.substring(0,4)} : ${data}`,);
}
}
3-1. 게이트웨이를 모듈에 등록하기
게이트웨이는 다른 클래스에 주입해서 사용할 수 있는 프로바이더이다.
@Module({
imports: [],
controllers: [AppController],
providers: [AppService, ChatGateway], // 게이트웨이를 프로바이더로 등록, 게이트웨이는 다른 클래스에 주입해서 사용할 수 있는 프로버이더이다.
})
4. 클라이언트를 위한 index.html 수정
웹소켓은 브라우저가 표준 프로토콜이라서 자체적으로 지원을해서 따로 라이브러리를 사용할 필요가 없다.
반면 socket.io는 브라우저에서 따로 지원을 안해줘서 설정을 해줘야한다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h2>Simple Nest Chat</h2>
<div id="chat"></div>
<input type="text" id="message" placeholder="메시지를 입력해주세요.">
<button onclick="sendMessage()">전송</button>
</body>
<!-- jquery 로드 -->
<script src="https://code.jquery.com/jquery-3.6.1.slim.js">
</script>
<!-- socket.io 인스턴스 생성 -->
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
<script>
const socket = io('http://localhost:3000');
// 전송 버튼을 클릭 시 입력된 글을 message 이벤트로 보냄
function sendMessage(){
const message = $('#message').val();
socket.emit('message', message);
}
socket.on('connect', () =>{
console.log('connected');
});
socket.on('message', (message) =>{
$('#chat').append(`<div>${message}</div>`);
});
</script>
</html>
socket.on('이벤트', '받은 데이터') : emit()에서 발생된 이벤트리스너로 데이터를 받는다
socket.emit('이벤트', '넘겨줄 데이터') : 서버에서 해당 이벤트를 발생시켜 클라이언트 쪽의 해당 이벤트 리스너에게 데이터를 넘겨준다.
'WEB > WebSocket' 카테고리의 다른 글
NameSpace 설정하기 (0) | 2024.05.10 |
---|---|
웹소켓 (0) | 2024.05.04 |