SSE와 WebSocket의 차이를 알아보자
WebSocket은 먼저 http통신으로 핸드쉐이크 후, 웹소켓 프로토콜 통신으로 바뀐다.
SSE는 text/event-stream 미디어타입으로 http통신을 연결 후, 그 연결이 닫히지 않는다.
여기서 주의점은 netty가 아닌, tomcat기반의 스프링으로 sse를 구현하면, http통신은 tomcat의 쓰레드풀에서 연결 하나당 하나의 쓰레드가 관리하므로, 쓰레드풀이 만약 200개라면, 200개의 sse커넥션이 넘어가면 쓰레드가 다 차버린다;;
그럼 websocket은? http통신으로 연결수립이 끝나면, spring내에서 구현되어있는 비동기 이벤트루프로 구현되어있는 시스템에서 관리된다고 한다.
또 websocket은 연결을 한부라우저에서 서버가 버티는한 무한대로 연결을 수립할수있찌만, sse는 http에서는 6개, http2에서는 200개까지만 한브라우저에서 연결 할 수 있다.
Websocket은 계속 연결을 수립하기위해 handshake를 한다.
sse는 무한 대기하다가 timeout나면 자동으로 재연결 수립을 한다.
그러므로 데이터의양 자체는 Websocket이 많으며, 속도는 유의미한 차이를 보이지 않는다.
그러나 sse는 재연결 수립과정에서 시간이 걸릴수 있고, 이때 이벤트 수신을 놓칠 수 있기때문에 관련된 로직을 적절히 처리해줘야하고,
websocket은 재연결수립 관련된 로직을 적절히 처리해줘야한다.
Websocket이 계속 핸드쉐이크를 통해 상태를 체크하니 안정성은 더 높다.
그런데, 만약 AWS ALB를 사용한다면 sse구현시 주의해야한다. ALB는 http 요청 후 일정시간이 지나면 timeout을 return 해버리고 요청을 끊어버리는데, sse는 http연결 후, 응답을 계속 기다리는 구조이다보니, 그 제한시간동안 아무런 데이터를 수신받지 못하면 요청이 끊긴다.
그리고 다시 연결 재시도...
그리고 그사이에 데이터를 수신받지 못하면? 관련로직을 또 추가해야해서 귀찮아짐..
방법 중 하나로 그 timeout시간에 맞춰서 dummy데이터를 보내는 방식을 사용 할 수 있다.
Spring에서 로깅한다고 무지성 ContentCachingRequestWrapper로 씌워버리면 안된다. text/event-stream은 데이터의 길이가 고정이면 안된다. 그런데 ContentCachingRequestWrapper로 씌워버리면 안에있는 데이터를 읽게되고, 그 순간 데이터의 길이가 고정되어 연결이 끊기게 된다.