ws 모듈로 웹 소켓 사용하기
연결 후에는 웹 소켓 서버(wss)에 이벤트 리스너를 붙입니다. 웹 소켓은 이벤트 기반으로 작동한다고 생각하면 됩니다. 실시간으로 데이터를 전달받으므로 항상 대기하고 있어야 합니다. connection 이벤트는 클라이언트가 서버와 웹 소켓 연결을 맺었을 때 발생합니다. req.headers['x-forwarded-for'] || req.connection.remoteAddress는 클라이언트의 IP를 알아내는 유명한 방법 중 하나이므로 알아두는 게 좋습니다. 익스프레스에서는 IP를 확인할 때, proxy-addr 패키지를 사용하므로 이 패키지를 사용해도 괜찮습니다. 로컬 호스트로 접속할 경우, 크롬에서는 IP가 ::1로 뜹니다. 다른 브라우저에서는 ::1 외의 다른 IP가 뜰 수 있습니다.
익스프레스 서버와 연결한 후, 웹 소켓 객체(ws)에 이벤트 리스너 세 개, 즉 message, error, close를 연결했습니다. message는 클라이언트로부터 메시지가 왔을 때 발생하고, error는 웹 소켓 연결 중 문제가 생겼을 때 발생합니다. close 이벤트는 클라이언트와 연결이 끊겼을 때 발생합니다.
setInterval은 3초마다 연결된 모든 클라이언트에 메시지를 보내는 부분입니다. 먼저 readyState가 OPEN 상태인지 확인합니다. 웹 소켓에는 네 가지 상태가 있습니다. CONNECTING(연결 중), OPEN(열림), CLOSING(닫는 중), CLOSED(닫힘)입니다. OPEN일 때만 에러 없이 메시지를 보낼 수 있습니다. 확인 후 ws.send 메서드로 하나의 클라이언트에 메시지를 보냅니다. close 이벤트에서
setInterval을 clearInterval로 정리하는 것도 꼭 기억해두기 바랍니다. 이 부분이 안되면 메모리 누수가 발생합니다. 프로그래밍을 할 때는 이렇게 사소한 것이 큰 영향을 미치기도 합니다.
웹 소켓은 단순히 서버에서 설정한다고 해서 작동하지는 않습니다. 클라이언트에도 웹 소켓을 사용해야 합니다. 양방향 통신이기 때문입니다. views 폴더를 만들고 index.html 파일을 작성하여, Script 태그에 웹 소켓 코드를 넣겠습니다. views 폴더 안에 error.html도 같이 작성합니다.
views/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>GIF 채팅방</title>
</head>
<body>
<div>F12를 눌러 console 탭과 netwrork 탭을 확인하세요.</div>
<script>
const webSocket = new WebSocket(`ws://localhost:8005`);
webSocket.onopen = function () {
console.log("서버의 웹 소켓 연결 성공!");
};
webSocket.onmessage = function (event) {
console.log(event.data);
webSocket.send("클라이언트에서 서버로 답장을 보냅니다");
};
</script>
</body>
</html>
views/error.html
<h1>{{message}}</h1>
<h2>{{error.status}}</h2>
<pre>{{error.stack}}</pre>
WebSocket 생성자에 연결할 서버 주소를 넣고 webSocket 객체를 생성합니다. 서버 주소의 프로토콜이 ws인 것에 주의하세요. 클라이언트에서도 역시 이벤트 기반으로 동작합니다. 서버와 연결이 맺어지는 경우에는 onopen 이벤트 리스너가 호출되고, 서버로부터 메시지가 오는 경우에는 onmessage 이벤트 리스너가 호출됩니다. 서버에서 메시지가 오면 서버로 답장을 보냅니다.
서버를 실행하는 순간, 서버는 클라이언트에게 3초마다 메시지를 보내고, 클라이언트도 서버로부터 메시지가 오는 순간 바로 답장을 보냅니다. 브라우저와 노드 콘솔에서 결과를 확인해봅시다.
http://localhost:8005에 접속하여 개발자 도구(F12)의 Console 탭을 엽니다. 접속하는 순간부터 노드의 콘솔과 브라우저의 콘솔에 3초마다 메시지가 찍힙니다.
8005 번 포트에서 대기 중
새로운 클라이언트 접속 ::1
클라이언트에서 서버로 답장을 보냅니다
클라이언트에서 서버로 답장을 보냅니다
클라이언트에서 서버로 답장을 보냅니다
...

Network 탭에 들어가면 웹 소켓이 무엇인지 확실히 알 수 있습니다.

서버로부터 3초마다 메시지가 오지만, 보낸 네트워크 요청은 처음 http://localhost:8005를 요청한 것과 웹 소켓을 요청한 것 두 번뿐입니다. HTTP를 사용하는 폴링 방식이었다면 매번 요청을 보내서 응답을 받아와야 했을 것입니다. 웹 소켓을 통해 주고받은 내용은 웹 소켓 항목을 클릭한 후 Messages 탭에서 볼 수 있습니다.

크롬 외 다른 브라우저를 열어 http://localhost:8005에 접속해봅시다. 다른 브라우저에서도 역시 3초마다 서버로부터 메시지가 옵니다.

클라이언트에서 서버로 답장을 보냅니다
클라이언트에서 서버로 답장을 보냅니다
클라이언트에서 서버로 답장을 보냅니다
GET / 200 3.361 ms - 596
새로운 클라이언트 접속 ::1
GET /favicon.ico 404 4.067 ms - 1421
클라이언트에서 서버로 답장을 보냅니다
클라이언트에서 서버로 답장을 보냅니다
클라이언트에서 서버로 답장을 보냅니다
클라이언트에서 서버로 답장을 보냅니다
클라이언트에서 서버로 답장을 보냅니다
클라이언트에서 서버로 답장을 보냅니다
클라이언트로부터 노드 서버에 오는 메시지의 양이 이전에 비해 두 배가 되었습니다. 두 클라이언트와 연결 중이기 때문입니다.
이제 브라우저 하나를 종료하면 접속 해제라는 메시지가 뜨고, 메시지의 양이 다시 하나가 됩니다.
클라이언트에서 서버로 답장을 보냅니다
클라이언트에서 서버로 답장을 보냅니다
클라이언트에서 서버로 답장을 보냅니다
클라이언트 접속 해제 ::1
클라이언트에서 서버로 답장을 보냅니다
클라이언트에서 서버로 답장을 보냅니다
클라이언트에서 서버로 답장을 보냅니다
'프로그래밍 언어 > NODE JS' 카테고리의 다른 글
| 실시간 GIF 채팅방 만들기(1) (0) | 2026.01.20 |
|---|---|
| Socket.IO 사용하기 (0) | 2026.01.17 |
| ws 모듈로 웹 소켓 사용하기 (0) | 2026.01.11 |
| 웹 소캣 이해하기 (0) | 2026.01.08 |
| 테스트 커버리지 (0) | 2025.12.26 |