이 글은
실시간 알림 기능을 구현하기 위해 풀링, 웹소켓, SSE 중에 어떤 방법이 가장 적절한지 비교하는 포스팅입니다.
요구사항은
서버에서 클라이언트에게 실시간 알림을 전송할 수 있으면 됩니다.
웹소켓은
하나의 TCP 접속에 전이중 통신(양방향 통신) 채널을 제공하는 컴퓨터 통신 프로토콜입니다. 웹소켓은 HTTP 포트 80과 443 위에 동작하도록 설계되었으며 HTTP 프록시 및 중간 층을 지원하도록 설계되었으므로 HTTP 프로토콜과 호환이 됩니다. 또한 HTTP 폴링과 같은 반이중방식에 비해 더 낮은 부하를 사용하고 서버와 클라이언트 간의 실시간 데이터 전송을 가능하게 합니다.
웹소켓 프로토콜을 사용하기 위해 웹소켓 핸드셰이크에서 HTTP 업그레이드 헤더를 사용하여 HTTP 프로토콜에서 웹소켓 프로토콜로 변경해야 합니다.
아래는 웹소켓 핸드셰이크의 예시입니다.
// Client request
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
// Server response
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
Sec-WebSocket-key: key
HTTP 업그레이드 요청의 핵심입니다. 본질적으로 키의 의미는 WebSocket 연결을 여는 것을 의미한다고 합니다. 서버는 응답에 자체 키를 포함시켜서 클라이언트가 이를 검증한다고 합니다.
Sec-WebSocket-Protocol: sub protocols..
선호하는 순서대로 사용하려는 하나 이상의 WebSocket 프로토콜을 지정합니다. 서버는 응답에 프로토콜 목록 중에서 지원하는 프로토콜을 선택하여 반환합니다. (그런데 필수로 보내는 헤더는 아닌 것 같습니다) (서브 프로토콜 명세)
Sec-WebSocket-Version: version
클라이언트가 사용하려는 WebSocket 프로토콜 버전을 지정합니다. 현재 최신 버전은 13(표준)이라고 합니다. (버전 명세)
SSE는
Server Sent Event의 약어로 HTTP 연결을 통해 서버의 데이터를 실시간으로, 지속적으로 푸시하는 기술입니다. 초기에 연결이 수립되면 서버가 클라이언트에 지속적으로 데이터를 전송할 수 있습니다. 보통 연결을 맺고 이벤트 스트림을 수신하기 위해 서버에서 API를 제공합니다. SSE의 MIME 유형은 text/event-stream 유형입니다. SSE는 웹 표준으로 IE를 제외한 모든 브라우저에서 지원됩니다.
결국 큰 차이점을 말해보자면 WebSocket은 양방향(bidirectional)이고 SSE는 클라이언트가 수신만 가능하다(mono-directional) 라는 차이점이 있습니다.
Socket | Server-Sent-Event | |
브라우저 지원 | 대부분 브라우저에서 지원 | 대부분 모던 브라우저 지원(polyfills 가능) |
통신 방향 | 양방향 | 일방향(서버에서 클라이언트로) |
리얼타임 | Yes | Yes |
데이터 형태 | Binary, UTF-8 | UTF-8 |
자동 재접속 | No | Yes(3초마다 재시도) |
최대 동시 접속 수 | 브라우저 연결 한도는 없지만 서버 셋업에 따라 다름 | HTTP를 통해서 할 때는 브라우저당 6개 까지 가능 / HTTP2로는 100개가 기본 |
프로토콜 | WebSocket | HTTP |
베터리 소모량 | 큼 | 작음 |
Firewall 친화적 | Nope | Yes |
결론적으로
일단 풀링은 지속적으로 요청을 보내기 때문에 오버헤드가 심하고 최선의 방식도 아닙니다. 웹소켓도 사용할 수는 있지만 양방향 통신은 필요없기 때문에 SSE를 사용하는 것이 가장 적절하다는 판단을 내렸습니다. 따라서 SSE를 사용하여 알람 기능을 구현하도록 하겠습니다.
Ref
https://ko.wikipedia.org/wiki/%EC%9B%B9%EC%86%8C%EC%BC%93#cite_note-2
https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism
'Spring' 카테고리의 다른 글
Spring Security에서 BadCredentialsException만 발생할 때 (0) | 2023.06.27 |
---|---|
스프링 로깅 기능 구현하기 (인터셉터, ThreadLocal 사용) (0) | 2022.09.13 |
테스트 코드 커버리지의 종류 (0) | 2022.08.16 |
단위 테스트 given-when-then 패턴과 BDDMockito (0) | 2022.08.08 |
Spring Security Form Login 사용과 동시성 세션 제어 (0) | 2022.07.17 |