[WebSocket] 웹소켓을 알아봅시다.

3 분 소요

%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA_2024-10-14_%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE_4 52 10

웹소켓을 알아봅시다.

HTTP (HTTP/1.1 이하)

클라이언트가 서버에게 요청(Request)을 보내고 서버가 그에 응하여 응답(Response)을 보내는 식으로 단방향 소통

서버가 클라이언트에게 메시지를 보내는 건 클라이언트의 요청에 응답을 할 때 뿐

서버가 먼저 클라이언트에게 메시지를 보내지 않는다.

채팅앱

내가 상대방에게 메시지를 보내는 것: 클라이언트 → 서버

상대방이 나에게 메시지를 보냈을 때: 서버 → 클라이언트

서버가 먼저 클라이언트에게 메시지를 보내지 않는다.

⇒ 내 앱에서 감지하는 것이 불가능

  • 서버에 들어온 상대방 메시지를 서버가 보낼 수 없음
  • 클라이언트의 요청 없이 서버에서 메시지를 보내지 못하기 때문

HTTP를 사용해서 문제 해결방법

  • Polling
    1. 클라이언트가 주기적으로 서버에 요청을 보내서 상대가 새 챗을 보냈는 지 확인
    2. 서버는 업데이트가 있을 때 있다고 응답, 없다면 없다고 응답

    문제

    • 요청을 보내는 주기만큼의 지연 발생
      • 서버가 갖고 있는 상태의 변화에 즉각적으로 반응하지 못함
    • 계속해서 불필요한 요청 전송
      • 요청의 주기가 짧다면 반응 속도는 빨라짐, 트래픽 낭비 심해짐
  • Long Polling
    1. 서버가 클라이언트의 요청에 바로 응답하지 않고 업데이트가 발생할 때까지 대기
    2. 상대방이 챗을 보내거나 타임아웃으로 설정된 시간이 지나면 응답
    3. 응답이 오면 클라이언트는 바로 다시 요청을 보냄

    문제

    • 데이터의 업데이트에 반응하는 속도 빨라짐, 서버의 부담이 커짐
      • 서버가 클라이언트로부터 요청을 받을 때부터 응답을 보내기까지 클라이언트와의 연결이 지속됨
      • 동시에 여러 클라이언트가 서비스를 사용하면 그만큼의 연결을 유지해야 하므로 부하 발생
      • ⇒ 업데이트에 대한 반응이 느려짐
      • HTTP 요청과 응답에 포함되는 헤더 정보의 양도 매 번 부담

⇒ 클라이언트와 서버가 동등하게 메시지를 주고받을 수 있는, 양방향 통신이 가능한 방식이 필요

HTTP/2와 WebSocket 비교

HTTP/2는 공중전화 부스에서의 제한된 통화

  • 장시간 양방향 통신을 위해 설계한 것이 아님
  • 서버에서 푸시를 보내는 게 가능하지만 클라이언트의 초기 요청에 대한 응답의 일부이다.
  • 연결의 지속을 위해 주기적인 요청과 응답이 필요
  • 브라우저에서의 사용에는 아직 제한되는 부분이 많다.

WebSocket은 스마트폰을 통한 자유로운 통화

WebSocket 통신

  1. 클라이언트에서는 서버에게 WebSocket을 연결하자는 요청을 HTTP를 통해 보냄.
  2. 서버는 수락하는 응답을 HTTP 로 보냄

(handshake)

  1. 연결이 이뤄지고 나면 그 때부터 클라이언트와 서버는 HTTP가 아닌 WebSocket 프로토콜을 사용하여 소통

    (ws:// or wss://)

  2. 클라이언트와 서버는 자유롭게 서로에게 메시지를 보낼 수 있다.
  3. 한 쪽이 close 프레임을 보내면 다른 쪽이 이를 확인하고 close 프레임을 응답으로 보냄으로써 연결이 종료
    • 비정상적인 종료를 감지 방법
      • 지정된 시간동안 메시지가 없을 시 확인 패킷을 보내는 방법
      • 주기적으로 ping, pong 프레임을 주고받아서 서로의 접속 여부를 확인하는 방법

카카오톡 채팅의 경우 방을 나가지 않는 이상 계속해서 클라이언트와 서버가 연결되어있는건가? ⇒ 비효율적이지 않나? - 어쩔 수 없나 댓가

장점

  • 헤더의 크기가 작고 오버헤드가 적기 때문에 HTTP보다 효율적인 통신이 가능
  • 하나의 연결을 끝까지 유지하고, 그 과정에서도 적은 자원만 소모하기 때문에 Long Polling만큼 서버에 부담을 주지 않음

Handshake

  1. 클라이언트의 요청의 헤더 (우편물에 붙은 송장)

    %E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA_2024-10-14_%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE_5 37 15

    • Upgrade: websocket , Connection: Upgrade : HTTP 연결을 WebSocket 프로토콜로 업그레이드 하자
    • Sec-WebSocket-Key : 클라이언트가 랜덤으로 생성한 값을 Base64로 인코딩한 문자열
  2. 서버의 응답의 헤더

    image

    • Sec-WebSocket-Accept : 서버는 요청을 받고 나서, GUID라 불리는 정해진 문자열을 그 키에 이어붙인 뒤 SHA-1 해시로 계산하여 다시 base64로 인코딩
  3. 클라이언트는 이것이 자기가 보낸 키로부터 생성된 값이 맞는지 확인

    • 클라이언트는 이 응답이 자신 요청을 보낸 상대로부터 온 것임을 확인
    • 자유롭게 양방향 소통 시작 (Open Connection)

TCP 소켓 / UDP 소켓

WebSocket - 7 layer (Application layer)

TCP socket, UDP socket - 4 layer (Transport layer)

WebSocket은 TCP 소켓을 기반으로 작동

  • 데이터의 순서와 신뢰성 보장

WebSocket 한계

  • 서버의 설계에 따라 구현이 복잡
  • 특히 로드 밸런싱이 적용된 서버에서는 고려하고 설정할 부분이 많아짐
    • 웹 소켓은 특정 서버와의 지속적인 연결 안에서만 이뤄지기 때문에 한 서버와 웹 소켓 통신을 시작하면 이후로도 계속 그 서버로만 데이터가 전송되도록 설정해야함
    • ⇒ NGINX, HAProxy, AWS ELB 등 WebSocket을 처리할 수 있는 로드 밸런서를 선택하여 구성한다
  • 메시지의 크기가 제한
    • 브라우저, 서버, 네트워크 환경마다 WebSocket에서의 메시지 크기에 제약을 둘 수 있음
    • 대용량 데이터의 경우, 분할해서 전송하거나 다른 프로토콜을 사용하는 등의 방법 사용
  • WebSocket의 기본 프로토콜인 WS은 통신이 암호화되어 있지 않다
    • 보안이 중요한 서비스라면 SSL/TLS 인증서를 발급받은 뒤 이를 사용하여 WSS를 설정 (https 방식과 비슷)
  • Polling 등의 방식보다는 덜 하지만 WebSocket도 서버에 부담을 준다.
    • 많은 사용자들이 동시에 접속해 있을수록 유지해야 하는 TCP 연결이 많아지고 메시지들이 오가는 빈도가 높다면 네트워크 대역폭과 CPU 사용량 증가

* 로드 밸런싱 : 서버 여러 대가 클라이언트 요청을 나눠서 받는 방식

카테고리:

업데이트: