[SSE(Sever-Sent-Events) - 단방향 통신 구현해보기]
Spring Boot Server-Sent-Events
개요
토이프로젝트를 진행하던 중, 클라이언트의 정보가 갱신이 될 때마다 다시 정보를 받아오기에는 무리가 있다고 생각했습니다. (언제 이벤트가 발생할 지 모르기 때문에) 따라서 어떤 유저의 정보가 갱신이 되면 서버 -> 클라이언트로 실시간 갱신을 위해 사용되는 방식에 대해서 공부를 해보고 이를 구현해보면 도움이 될 것 같아서 해당 포스터를 작성했습니다.
서버 - 클라이언트 통신의 종류
앞서 설명드리기 전, HTTP 프로토콜은 비연결성이라는 특징을 가졌다는 것을 알려드립니다.
즉, A라는 사람이 이전에 연결이 한 적이 있더라도, 서버는 연결을 끊어버리므로 갱신된 데이터를 A에게 보낼 수 없게 됩니다.
1. Polling 방식 (폴링 , 긴폴링)
- 해당 방식은 클라이언트가 일정한 주기로 서버에게 데이터를 요청합니다. 일정 주기를 가지고 계속해서 요청을 하므로, 리소스의 낭비가 발생할 수 있습니다.
1.1 Polling
- 다음 그림과 같이 client가 주기적으로 서버에게 request를 보내게 되고, response를 받는 방식입니다.
- 이러한 방식을 사용하게 된다면 request를 보냈을 때, 메세지가 없는 경우에도 reponse를 보내게 됩니다. 또한 초 간격을 늘렸을 경우, 실시간성이라고 보기 어렵습니다.
- HTTP는 단발성 통신으로 header가 매우 무거운 프로토콜중 하나로 계속해서 request를 보내게 되면 서버의 부담이 증가하게 된다.
1.2 Long Polling
- Polling의 단점을 보완한 방식입니다.
- Polling과는 다르게 request를 보낸 후, 즉시 response를 보내지 않고 timeout이 날 때까지 기다렸다가 이벤트가 발생했을 때 response를 보내는 방식입니다.
- 하지만 서버의 이벤트가 빈번하게 발생할 경우, 일반적인 Polling과 같은 방식으로 서버의 부담이 증가하게 됩니다.
2. Streaming 방식
앞의 request에 대한 response를 내려 connection을 종료하는 것이 아니라, 유지하면서 서버가 계속 데이터를 보내는 방식입니다. 또한 클라이언트가 서버에게 메세지를 보내고 싶을 경우 새로운 커넥션을 맺습니다.
2.1 Web Socket 방식
앞선 설명에서 클라이언트가 서버에게 보내래면 새로운 커넥션을 맺어야 한다고 했습니다. 이 경우 Request/Response 헤더가 불필요하게 크기 때문에 이를 해결하기 위한 Web Socket 방식에 대해서 알아보겠습니다.
- 웹 소켓은 HTTP와 같은 프로토콜이 일종으로 클라이언트와 서버간의 효율적인 양방향 통신을 실현하기 위한 구조입니다.
- XMLHttpRequest 통신을 할 때, 통신할 때마다 요청헤더가 부여되기 때문에 필요하지 않는 정보들을 보내게 됩니다. 그래서 아주 작은 데이터를 송수신하는데에도 이러한 정보들을 보내기 때문에 실시간 통신에서 성능차이가 날 수 있습니다.
2.2 Sever-Sent-Events(SSE) 방식
- 웹소켓과 달리, 클라이언트로는 서버로부터 데이터를 받을 수만 있습니다.
별도의 프로토콜을 사용하지 않고, HTTP 프로토콜만 사용하므로 훨씬 가벼운 장점이 있습니다.
-
앞서 설명드렸던 Web Socket 방식은 양방향 통신에 적합합니다. 채팅과 같은 데이터를 실시간으로 주고받는 경우에 좋은 선택이지만 현재 프로젝트에서는 서버에서 업데이트 된 내용을 클라이언트에게 보내는 단방향 통신이 적합하다고 생각하였습니다.
구현 과정
- 추가 예정
Reference
[양방향 통신 방법] Polling vs WebSocket [Spring + SSE] Server-Sent Events를 이용한 실시간 알림 [SQS] Long Polling & Short Polling