티스토리 뷰

1. Web Socket 통신의 이해

2. ws 모듈을 이용한 구현


1. Web Socket 통신의 이해

[그림 1] Ajax polling vs. Web Socket

Web Socket을 사용하기 전에 이것이 어떤 기능을 하고, 왜 사용하는가에 대해서 먼저 생각해 보아야 한다.

 

http는 네트워크를 통해 웹 브라우저가 웹 서버로부터 데이터를 가져오기 위한 통신 방법으로 사용된다. http 통신 이외에도 Web Socket 통신을 이용하여 데이터를 주고받을 수 있다.

 

그렇다면 http 통신만 사용해도 충분할 것 같은데 굳이 왜 Web Socket 통신도 쓰는걸까?

 

http 통신은 클라이언트의 요청이 있을 때에만 서버가 응답하여 정보를 전송하고, 곧바로 연결을 끊는 방식이다. 즉, 클라이언트가 요청을 보내고 서버가 응답하는 단방향통신 (stateless : 연결상태유지X) 이다. 실시간이 아니라 필요한 경우에만 서버로 접근하는 콘텐츠 위주의 데이터를 사용할 때 용이하다. 예를 들어, 누군가 나의 블로그에 들어오는 경우 웹 브라우저가 웹 서버로 글에 대한 내용을 보내달라고 요청하여 서버가 전달해주고 바로 연결을 종료하면 된다.

 

기존 웹 페이지에서 사용하는 http는 요청/응답 패러다임이기 때문에 클라이언트가 요청을 보내야만 그에 대한 응답을 받는다. 옛날 홈페이지의 경우 동적인 홈페이지가 거의 없었기 때문에 별 문제가 없었지만 최근 웹 사이트는 동적인 기능을 많이 요구하고 있다. 이에 따라 클라이언트가 요청을 보내지 않아도 서버에서 클라이언트쪽으로 데이터를 보내야 하는 경우도 발생하였다.

 

하지만, http 통신은 연결이 유지되지 않아 서버에서 먼저 요청을 보내는 것이 불가능하다. 그래서 Polling, Long Polling, Streaming 방식을 이용하여 비슷한 효과를 구현할 수 있다.

 

[그림 2] Polling

Polling은 클라이언트가 일정 주기마다 요청을 보내고 서버는 현재 상태를 바로 응답하는 방식이다. 이 방식은 실시간으로 반영되는 것이 중요한 서비스에는 별로 좋지 않고 서버에서 변화가 없더라도 매 요청마다 응답을 주기 때문에 불필요한 트래픽이 발생하게 된다.

 

[그림 3] Long Polling

Long Polling은 클라이언트가 요청을 보내고 서버에서는 이벤트가 발생했을 때 응답을 주고 클라이언트가 응답을 받았을 때 다시 다음 응답을 기다리는 요청을 보내는 방식이다. 이 방법은 실시간 반응이 가능하고 Polling에 비해 불필요한 트래픽을 유발하지는 않지만 오히려 이벤트가 잦으면 순간적으로 과부하가 걸리게 된다.

 

[그림 4] Streaming

Streaming은 이벤트가 발생했을 때 응답을 주는데 응답을 완료시키지 않고 계속 연결을 유지하는 방식이다. Long Polling에 비해 응답마다 다시 요청하지 않아도 되므로 효율적이지만, 연결 시간이 길어질수록 연결의 유효성 관리의 부담이 발생한다.

 

위와 같은 방법들을 이용하여 양방향 통신을 구현할 수도 있지만, HTML5에서 소켓 연결을 하는 Web Socket이 표준으로 등록되어 이를 이용하여 서버-클라이언트 간의 양방향 통신을 구현할 수 있게 되었다.

 

Web Socket 통신은 클라이언트와 서버가 특정 port를 통해 연결을 성립하고 있어서, 실시간으로 양방향 통신을 하는 방식이다. 클라이언트가 서버한테만 요청을 보내는 http와 달리 서버도 클라이언트한테 요청을 보낼 수 있는 양방향통신 (stateful : 연결상태유지) 이다. 계속 연결을 유지하는 연결지향형 통신이기 때문에 스트리밍중계나 실시간 채팅 등 실시간 통신이 필요한 경우에 자주 사용한다.

 

프로토콜은 ws(websocket)과 wss(websocket secure)를 사용하고 포트는 http(80), https(443)와 동일한 포트를 사용한다.

 

 

2. ws 모듈을 이용한 구현

먼저 아래의 명령어로 ws 모듈을 설치한다.

$ npm i ws

 

[그림 5] server.js 코드

app.listen() 부분을 webSocket()으로 감싸준다.

 

[그림 6] socket.js 코드

먼저 require로 ws 모듈을 불러온다. webSocket이라는 클래스를 객체로 생성하여 wss라는 변수를 선언한다.

 

웹 소켓과 서버가 같은 port를 쓰려면 5번째 줄과 같이 {server}를 적어주고, 다른 포트를 쓰려면 웹 소켓 통신을 하고자 하는 port를 지정하여 6번째 줄과 같이 {port:3090}으로 적으면 된다.

 

wss의 on()은 addEventListener()와 비슷한 역할을 한다.

 

connection이 되었을 때 req.headers에 sec-websocket-key가 담긴다. sec-websocket-key는 각 connection의 고유한 값으로, 100개의 connection이 생기면 100개의 키가 생성된다.

 

웹 브라우저로부터 message를 받았을 때에는 message의 타입이나 분류 방법에 따라 case를 다르게 하여 처리할 수 있다.

 

[그림 7] index.html 코드

index.html에서도 WebSocket 클래스를 객체로 생성하고 통신할 서버 주소는 ws://localhost:3000/로 지정하였다.

 

onopen과 onclose는 각각 connection이 맺어졌을 때와 끊어졌을 때 실행시킬 콜백 함수를 정해준다.

 

Web Socket은 json 형태로 데이터를 전송할 수 없기 때문에 JSON.stringify()를 이용해 문자열로 바꾸어 준 후 서버에 전송해야 한다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함