이번에 채팅 프로젝트를 진행하면서 채팅방 업데이트에 대한 요구사항을 만족시켜야하는 상황이 발생했다.
이전에 채팅방 메세지 내역은 웹소켓으로 구현을 해서 해당 채팅방에 접속하면 웹소켓에 접속하는 방식으로 해결했었다.
하지만 문제는 채팅방 목록에도 있었다. 채팅이 오면 채팅방 목록도 업데이트를 해야하는데 웹소켓으로 일일이 연결하자니 비효율적이라는 생각이 드는 것이다.
그래서 다른 방법을 찾아봤다.
먼저 아래 통신방법들은 웹소켓과 같이 HTTP 프로토콜의 특징 중 비연결성으로 인해 발생하는 문제를 해결하기 위한 방법들이다.
폴링은 HTTP의 비연결성에 대한 해결책으로, 계속 평범한 요청을 날려 이벤트가 발생한다면 그 이후의 요청을 통해 해당 이벤트에 대한 결과를 리턴해주는 것이다.
당연하지만 이런 방식은 클라이언트가 계속 요청을 보내면서 서버의 부담이 커진다.
그리고 연결을 맺고 끊는 것에 대한 비용 부담이 커지기 때문에 좋지 않을 뿐더러 실시간으로 동작한다고 보기도 어렵다. 주기적으로 보내는 것이기 때문에 바로 응답한다는 보장이 없기 때문이다.
하지만 주기적으로 갱신되는 데이터가 존재한다면 이러한 방식도 충분히 이용가능할 것이다.
- 클라이언트가 일정한 주기로 서버에 요청을 보낸다.
- 서버는 요청을 받으면 변경된 데이터가 있는지 확인하고, 새로운 데이터가 없다면 빈 응답을 반환한다.
- 클라이언트는 일정한 주기로 계속해서 서버에 요청을 보내어 변경된 데이터를 확인한다.
폴링의 변형으로, 클라이언트의 요청에 서버가 바로 응답하지 않고 일정 시간 동안 대기한 후에 변경된 데이터가 있으면 응답한다. 만약 변경된 데이터가 없다면 일정 시간 후에 응답 없음(Timeout) 상태로 응답한다. 이 경우 클라이언트는 다시 요청을 보내어 대기하게 된다.
이렇게 된다면 폴링 방식과 다르게 계속적으로 연결해두고 있다가 바로 그에 대한 결과값을 받기에 실시간성이 보장될 것이다. 또한, 이 방법은 기존 폴링 방식과 달리 지속적인 요청을 보내지 않아 그나마 부담이 덜하다.
하지만 시간 간격이 좁다면 사실상 기존 폴링과 큰 차이가 없게되고 지속적으로 연결되어 있기 때문에 다수의 클라이언트에게 동시에 이벤트가 발생될 경우 응답을 보내고 요청을 다시 보내야하기 때문에 순간적인 부담이 급증하게 된다.
결국 이벤트가 자주 발생하는 경우에는 부담이 될 수 밖에 없다.
- 클라이언트가 서버에 요청을 보낸다.
- 서버는 요청을 받으면 일정 시간 동안 대기한다.
- 만약 변경된 데이터가 있다면, 서버는 응답으로 해당 데이터를 전송한다.
- 변경된 데이터가 없다면, 일정 시간 후에 응답 없음(Timeout) 상태로 응답한다.
SSE는 웹소켓과 달리 단방향 통신 방식이다. 서버에서 클라이언트로 지속적인 연결을 유지하며, 변경된 데이터를 스트리밍 형태로 전송한다. 이를 통해 실시간으로 메시지를 수신하여 채팅방 목록을 업데이트할 수 있다.
SSE의 장점 중 하나는 웹소켓과 달리 별도의 프로토콜을 사용하지 않고 HTTP 프로토콜만으로 사용할 수 있다는 점이다. 이로 인해 SSE는 더 가볍고 간단한 구현이 가능하다.
또한, HTTP/1.1의 경우 브라우저당 6개의 동시 접속만을 허용하는 제약이 있다. 하지만 HTTP/2에서는 최대 100개까지의 동시 접속을 허용하므로, SSE를 사용하는 경우에도 브라우저의 동시 접속 제한에 대해 고려해야 한다.
따라서 SSE는 경량화된 통신 방식으로서 채팅방 목록 업데이트와 같은 실시간 데이터 전송에 유용하게 활용될 수 있다.
- 클라이언트와 서버 사이에서 단방향 연결이 형성된다.
- 연결이 유지되면서 서버에서 변경된 데이터를 스트리밍 형태로 전송한다.
- 클라이언트는 이벤트 스트림(Event Stream)으로부터 메시지를 수신하여 처리할 수 있다.
채팅방 목록 업데이트는 메세지가 왔을때 목록을 실시간으로 '업데이트 해라'라는 알림만 주면 된다. 또한 서버에서 클라이언트로 데이터를 전송해주기만 하면 되기 때문에 단방향 통신으로 충분하다.
먼저 실시간성을 고려하면 Polling, Long Polling은 적합하지 않다.
또한 단방향 통신으로 충분히 구현이 가능하기 때문에 웹소켓보다 구현이 단순하고 가벼운 SSE가 적합하다는 결론을 내릴 수 있다.
따라서 채팅방 목록 업데이트는 SSE를 이용하여 구현하기로 결정하였다.