ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 실시간 시스템 구현을 위한 WebSocket의 이해
    Web 2021. 10. 22. 17:14

    WebSocket에 대해 깊이있게 이해하기 위해 Spring 공식 문서를 보면서 다시 공부해봤다.
    이번 글에서는 Raw 웹소켓 상호작용을 포함하는 웹소켓 메시징 방식에 대해 알아본다. 다음 글에서는 WebSocket 스택이 지원되지 않는 브라우저에서도 에뮬레이션을 지원하는 SockJS, Pub/Sub 모델 기반의 하위 프로토콜인 STOMP에 대해 다루고자 한다.

     

    Introduction to WebSocket

    웹 소켓 프로토콜은 단일 TCP 연결을 통해 클라이언트-서버 간 양방향 통신 채널의 설정을 제공한다. HTTP와는 다른 프로토콜이지만 HTTP 위에서 작동할 수 있도록 설계되어 Port 80과 443을 사용하고 기존의 방화벽 규칙을 사용할 수 있다.

    WebSocket 상호 작용은 HTTP Upgrade 헤더를 사용해서 업그레이드하는데, 이 프로토콜로 전환하는 HTTP 요청으로 WebSocket 통신이 시작된다.

    GET /spring-websocket-portfolio/portfolio HTTP/1.1
    Host: localhost:8080
    Upgrade: websocket 
    Connection: Upgrade 
    Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==
    Sec-WebSocket-Protocol: v10.stomp, v11.stomp
    Sec-WebSocket-Version: 13
    Origin: http://localhost:8080
    • Upgrade: websocket → WebSocket을 사용한다
    • Connection: Upgrade → Upgrade 커넥션을 사용한다

    해당 요청에 대해 일반적인 200 상태코드를 반환하는 대신, (WebSocket을 지원하는) 서버는 다음과 같은 출력을 반환한다.

    HTTP/1.1 101 Switching Protocols 
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=
    Sec-WebSocket-Protocol: v10.stomp
    • HTTP/1.1 101 Switching Protocols → 프로토콜을 변경한다

    위의 핸드셰이크가 성공한 후, HTTP 업그레이드 요청의 기반이 되는 TCP 소켓은 클라이언트-서버 간 메시지 통신을 할 수 있도록 계속 열려있다.

    WebSocket의 구체적인 작동방식에 대해서는 아래의 원문, 참고자료를 공부하자 ❗

    rfc6455

     

    rfc6455

     

    datatracker.ietf.org

    NAVER D2

    웹 소켓 - Web API | MDN

     

    웹 소켓 - Web API | MDN

    웹 소켓은 사용자의 브라우저와 서버 사이의 인터액티브 통신 세션을 설정할 수 있게 하는 고급 기술입니다. 개발자는 웹 소켓 API를 통해 서버로 메시지를 보내고 서버의 응답을 위해 서버를

    developer.mozilla.org

    웹소켓 서버가 NginX와 같은 웹 서버 뒤에서 실행되는 경우, 웹소켓 업그레이드 요청이 프록시 서버를 넘어 웹소켓을 실제 지원하는 서버까지 전달하도록 구성해야 한다. 마찬가지로 애플리케이션이 클라우드 환경에서 실행될 경우 WebSocket 지원과 관련된 지침 또한 참고해야 할 것이다.

     

    HTTP 🆚 WebSocket ❓

    웹소켓에 대해 이해했다면 "웹소켓, HTTP 통신이 정확이 어떻게 다른데??"라는 고민이 생긴다.

    기본적으로 웹소켓은 HTTP와 호환되도록 설계되었고 HTTP 요청으로 핸드셰이킹이 발생하지만, 두 프로토콜은 매우 다른 아키텍처와 애플리케이션 결과물을 만든다.

     

    HTTP와 REST에서 애플리케이션은 End-Point에 해당하는 URL 수만큼 모델링된다. 또한 애플리케이션과의 상호작용을 위해 클라이언트는 Request-Response 방식의 URL에 액세스한다. 서버는 HTTP URL와 메서드, 헤더에 따라 Request를 적절한 핸들러로 라우팅한다.

    하지만 웹소켓에선 일반적으로 초기 연결 수립을 위한 하나의 URL만 있다. 이후 모든 애플리케이션 메시지는 해당 TCP 연결 위에서 흐른다. 이는 HTTP 통신과 구분되는 완전한 비동기 이벤트 기반 메시징 아키텍처(Asynchronous, Event-Driven Messaging Architecture)를 나타낸다.

     

    웹소켓은 Low-level의 통신 프로토콜이며, HTTP와는 다르게 메시지 내용에 대해 규정하지 않는다. 즉, 클라이언트와 서버가 메시지 형식에 대해 합의하지 않는 이상 메시지 자체를 라우팅하거나 처리할 수 있는 방법이 없다는 걸 의미한다.

    웹소켓 클라이언트와 서버는 HTTP 핸드셰이크 요청에서 Sec-WebSocket-Protocol 헤더와 같은 조금 더 고차원의 메시징 프로토콜 사용을 협의할 수 있다. 그게 없을 경우에는 고유한 컨벤션을 정의하는 과정이 필요할 것 이다.

     

    When to Use WebSockets

    웹소켓은 실시간 시스템을 더욱 dynamic하고 interactive하게 만드는 하나의 방식이다. 하지만 많은 경우에서 꼭! 웹소켓을 사용하는 것만이 정답은 아니며, Ajax + HTTP streaming / Long polling을 사용하는 게 더 적합한 상황도 있다.

    스프링 공식 문서에서 소개하기를, 뉴스/메일/소셜 피드 같은 경우에는 동적인 업데이트를 요구하지만 엄격한 실시간성 보다는 큰 분단위의 업데이트가 더 적합할 수 있다. 반면 Notion과 같은 협업이나 게임, 금융 애플리케이션 같은 경우는 실시간 시스템의 성격을 더 강하게 띤다.

    대기 시간뿐만이 아니라, 네트워크 장애 모니터링 시스템과 같이 메시지의 양이 적은 시스템의 경우에도 HTTP Streaming과 폴링이 더 적합할 수 있다.

    즉, 웹소켓이 가장 적절하게 활용될 수 있는 시스템은 짧은 지연시간+높은 빈도수+많은 양의 데이터가 실시간으로 오가는 시스템이다.

     

    WebSocket의 내부 Raw API 구현에 대해서는 아래의 링크를 참조하자.

    https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#websocket-server

     

    Web on Servlet Stack

    Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, “Spring Web MVC,” comes from the name of its source module (spring-webmvc), but it is more com

    docs.spring.io

     

    정리

    WebSocket은 클라이언트-서버 간 실시간 양방향 통신을 위해 사용되는 프로토콜이다.
    초기 커넥션 수립 시 HTTP를 이용하며, 해당 TCP 커넥션을 통신을 위해 사용한다.
    실시간 통신을 위해서는 HTTP stream, Polling 방식도 있으나 WebSocket이 실시간 시스템 + 높은 트래픽을 가진 애플리케이션에 적용하기에 적합한 기술이다.
Designed by Tistory.