표준 웹소켓: 서버 간에 실시간 통신을 위해 설계된 HTML5 웹 표준 기술. 하나의 TCP 연결을 통해 양방향 통신을 가능하게 하며, 오버헤드가 적고 속도가 빠르다.
HTML5 이전의 기술로 구현된 서비스나 웹소켓을 지원하지 않는 브라우저에서는 웹소켓이 동작하지 않는다. WebSocket Emulation을 가능케하는 Socket.io나 SockJS 같은 자바스크립트 라이브러리를 사용한다면 이를 해결할 수 있다.
WebSocket Emulation
먼저 웹 소켓으로 연결을 시도하고, 실패할 경우 HTTP Streaming, Long-Polling 같은 HTTP 기반의 다른 기술로 전환해 다시 연결을 시도하는 것
웹소켓 에뮬레이션은 아래와 같은 상황에서 브라우저에 영향없이 원래의 통신 기능을 가능하게 해준다.
- WebSocket을 지원하지 않는 브라우저
- Server/Client 중간에 위치한 Proxy가 Upgrade 헤더를 해석하지 못해 서버에 전달하지 못한 상황
- Server/Client 중간에 위치한 Proxy가 유휴 상태 커넥션 조기 종료됨
node.js
를 사용한다면 Socket.io
를 사용하고, Spring
(STOMP만 지원)을 사용하면 SockJS
를 사용하는 것이 일반적이다.
Socket.io
클라이언트와 서버 간의 실시간 양방향 통신을 위해 설계된 실시간 메시징 라이브러리
- 지연 시간이 짧고, 확장 가능한 아키텍쳐
- 자체 전송 프로토콜
Engine.IO
를 사용
- fallback 메커니즘
- 소켓 연결을 설정할 수 없을 경우 HTTP 롱 폴링 등 다른 메커니즘을 이용하여 실시간 통신을 지원
- 룸, 사용자 지정 이벤트 또는 멀티플렉싱 등의 추가 기능
WebSocket과 API 호환이 되지 않는다!
표준 웹소켓 클라이언트는 Socket.IO 서버에 연결할 수 없고, Socket.IO 클라이언트도 표준 웹소켓 서버와 함께 작동할 수 없다.
- three handshaking을 하지 않기 때문!
- 또한 socket.io는 WebSocket을 사용하지만 각 패킷에 추가 메타데이터 추가하여 사용한다.
SockJS
웹소켓 API를 모방하여 웹소켓이 지원되지 않는 경우에도 유사한 기능을 제공하는 자바스크립트 라이브러리
- HTTP 롱 폴링과 같은 메서드에 대한 fallback 제공
- 웹소켓을 에뮬레이션하도록 설계 - 웹소켓 API 호환
- 추가 기능 범위 제한됨
SockJS의 핵심 아이디어는 개발자가 WebSocket을 사용할 수 없는 상황에 대비할 필요가 없도록 보호하는 것이다.
- SockJS는 클라이언트와 서버를 연결하는 데 어떤 기술이나 프로토콜을 사용하든 동일한 API 제공한다.
STOMP
Simple Text Oriented Messaging Protocol
- HTTP에서 모델링 되는 Frame 기반 프로토콜
- TCP, 웹소켓과 같은 양방향 네트워크 프로토콜에서 사용
- 메시지 브로커를 활용하여 채팅 통신을 위한 형식을 정의
Publish-Subscribe
구조: 메시지를 공급하는 주체와 소비하는 주체를 분리해 메시징을 제공
Message Broker
: 발신자가 메시지를 발행하면 수신자들이 발행된 메시지를 수신하도록 메시지를 전달하는 주체
- Spring은 WebSocket 사용 시 STOMP를 지원함
STOMP의 Frame 구조
COMMAND
header1:value1
header2:value2
Body^@
Command
- 종류: CONNECT, SEND, SUBSCRIBE, UNSUBSCRIBE 등
Header
- key:value 형태로 정보를 포함
- Header와 Body는 빈 줄로 구분
Body
- 데이터(Payload)가 포함됨
- Body의 마지막은 NULL 문자로 설정됨
STOMP 통신 흐름
- 구독자들은 채팅방 구독
- 발신자 메시지 발송
- 메시지가 서버에서 처리 과정 거친 뒤 전달, 또는 즉각적인 Message Broker에 전달됨
- Message Broker는 특정 경로를 구독하고 있는 모든 구독자들에게 전달받은 메시지를 송신
참고자료
socket.io vs sockjs
websocket과 stomp이해하기
webSocket emulation과 sockjs