socket.io 를 사용하여 실시간 양방향 통신 작업을 하며 공부한 내용에 대하여 정리했습니다.
1. 웹 브라이저에서의 양방향 통신
기존 웹 페이지에서 사용하는 http 프로토콜은 무상태 프로토콜으로 요청/응답 패러다임으로 이루어져 있어 이전 요청과도 무관한 각각의 요청을 독립적인 트랜잭션으로 취급하며 클라이언트에서 요청을 보내야만 응답을 받을 수 있는 통신 프로토콜입니다. 하지만 동적인 기능이 많이 요구되면서 요청을 보내지 않아도 서버에서 클라이언트 쪽으로 데이터를 보내야 하는 경우가 많아졌습니다. 그래서 Polling, Long Polling, Streaming 방식을 이용하여 비슷한 효과를 구현하였습니다.
● Polling
클라이언트에서 일정 주기마다 요청을 보내고 서버는 현재 상태를 바로 응답하는 방식입니다.
이 방식은 실시간으로 반영되는 것이 중요한 서비스에는 별로 좋지 않고 서버에서 변화가 없더라도 매 요청마다 응답을 내려주기 때문에 불필요한 트래픽이 발생하게 됩니다.
● Long Polling
클라이언트에서 요청을 보내고 서버에서는 이벤트가 발생했을 때 응답을 내려주고 클라이언트가 응답을 받았을때 다시 다음 응답을 기다리는 요청을 보내는 방식입니다.
실시간 반응이 가능하고 polling에 비해서 불필요한 트래픽은 유발하지는 않지만 오히려 이벤트가 잦다면 순간적으로 과부하가 걸리게 됩니다.
● Streaming
이벤트가 발생했을때 응답을 내려주는데 응답을 완료시키지 않고 계속 연결을 유지하는 방식입니다.
Long Polling에 비해 응답마다 다시 요청을 하지 않아도 되므로 효율적이지만, 연결 시간이 길어질수록 연결의 유효성 관리의 부담이 발생합니다.
위와 같은 방법들을 이용하여 양방향 통신을 구현할 수도 있지만 이제는 HTML5에서 소켓 연결을 하는 websocket이 표준으로 등록되어 이를 이용하여 서버-클라이언트간의 동적인 양방향 통신을 구현할 수도 있게 되었습니다.
websocket
websocket이란 웹 서버와 웹 브라우저간 실시간 양방향 통신환경을 제공해주는 실시간 통신 기술입니다. 위의 Polling 방식(요청-응답방식)과 다르게 양방향으로 원할때 요청을 보낼 수 있으며 stateless한 HTTP에 비해 오버헤드가 적으므로 유용하게 사용할 수 있습니다.
socket.io
HTML5 WebSocket은 오래된 브라우저의 경우 지원하지 않는 경우가 있습니다. 브라우저 간 호환을 고려하여 Node.js를 위한 강력한 Cross-platform WebSocket API인 Socket.io를 사용하는것을 권장하고 있습니다.
Socket.io란 위에서 설명한 WebSocket과 같이 클라이언트와 서버의 양방향 통신을 가능하게 해주는 모듈입니다.
socket.io는 통신을 시작할 때, 각 브라우저에 대해서 websocket, pooling, streaming, flash socket 등에서 가장 적절한 방법을 찾아 메시지를 보내줍니다. 그 덕분에 socket.io를 통해 개발을 하면 websocket이 지원이 되지 않는 브라우저에서도 메시지를 양방향으로 주고 받을 수 있습니다.
2. Socket 사용방법
Server side 환경 (node.js)
- express : 4.15.4
- socket.io : 2.3.0
io.on(‘connection’, callback) 과 같이 연결되었을 때의 이벤트를 정의하고 각 소켓에 대해서 on(‘event’, callback) 과 같이 원하는 이벤트를 작성할 수 있습니다.
- 소캣 커넥션이 좋지않다면 재시도를 해보고 연결이 아예 안되는경우는 일반 api를 사용하게 작업했습니다.
Options
- path : '/someapi/socket.io' 를 사용하면 redirect 할 수 있습니다. 기본값 url 로 요청되던 socket.io이 url+특정우회주소 로 요청됩니다.
예를들어 base_url_socket이 tistory.com/ 라면, path를 추가하면 tistory.com/someapi/ 방식으로 소켓 커넥션이 요청됩니다. tistory.com/someapi 로 /someapi가 가리키는 포트로 redirect 되어 커넥션이 설정되고, /chat에 대한 Socket.io-client 연결이 생성됩니다.