개발 일기

[Computer Network] 실시간 웹 통신 - 3. 웹소켓 프로토콜(WebSocket Protocol) 본문

Computer Science/Computer Network

[Computer Network] 실시간 웹 통신 - 3. 웹소켓 프로토콜(WebSocket Protocol)

개발 일기장 주인 2024. 10. 9. 21:44

이전 게시글에선 Socket과 Socket 통신에 대해 알아봤고 이번에는 웹소켓에 대해 정리해보겠다.


웹소켓(WebSocket)

  • 초기의 인터넷 통신 방식인 HTTP를 통해 실시간 통신(Polling, Long Polling, SSE 등)을 구현하는 것에 한계점이 있어 이를 극복하기 위해 등장한 프로토콜이다.
  • 클라이언트와 서버 간의 실시간 네트워킹(Real-Time Networking)전이중 통신(양방향 통신: Full-Duplex)을 지원하는 프로토콜로 지속적인 연결을 유지하며 클라이언트와 서버 간의 실시간 데이터 전송을 가능케 한다.
  • HTTP 프로토콜을 사용하여 초기 연결을 설정
  • HTML5에 등장 실시간 웹 애플리케이션을 위해 설계된 통신 프로토콜이며, TCP(Transmission Control Protocol)를 기반한다.
  • WebSocket 프로토콜을 통한 통신은 헤더가 작아 오버헤드가 적음
  • 웹소켓을 위한 별도의 포트는 없으며, 기존 포트를 사용
  • 프레임으로 구성된 메세지라는 논리적 단위로 송수신 (텍스트와 바이너리 교환 가능)

웹소켓(WebSocket) 

https://www.youtube.com/watch?v=2oMPf-ueQic

  1. 클라이언트의 요청(HTTP Protocol 기반)
    클라이언트는 웹소켓 서버에 연결 요청을 보내기 위해 HTTP Upgrade 요청을 보낸다. 즉, 지금부터 HTTP로 통신하던 것을 WebSocket 통신으로 업그레이드 하자는 요청이다.
    • Upgrade: 웹소켓으로의 프로토콜 전환 요청
    • Connection: Upgrade 키워드 포함
    • Sec-WebSocket-Key: 웹소켓 핸드셰이크에 필요한 고유 키(클라이언트가 랜덤으로 생성한 16바이트 숫자값을 Base64로 인코딩한 문자열)
    • Sec-WebSocket-Version: 웹소켓 프로토콜의 버전
  2. 서버의 응답(HTTP Protocol 기반)
    서버는 클라이언트의 요청을 수신하고, 이를 승인하면 101 Switching Protocols 응답을 반환한다. 
    • Upgrade: 웹소켓 프로토콜Connection: Upgrade 키워드 포함
    • Sec-WebSocket-Accept: 클라이언트가 보낸 Sec-WebSocket-Key에 GUID라는 문자열을 뒤에 이어 붙혀 SHA-1 해시를 계산하고 해시 결과를 다시 Base64로 인코딩한 값으로 해당 공식은 고정이라 클라이언트에서 해당 값을 검증을 통해 서버가 키를 제대로 처리했는지 확인할 수 있다.
  3. 연결 완료(WebSocket Protocol 통신 시작)
    클라이언트는 서버의 응답을 수신하고, 연결이 성공적으로 이루어졌음을 확인 후 클라이언트와 서버는 웹소켓 프로토콜(ws:// 또는 wss://)을 사용하여 데이터 통신을 시작한다.

  4. 웹소켓 종료 요청 과정(WebSocket Protocol 기반)
    • 클라이언트 또는 서버가 연결 종료를 원할 경우, Close 프레임을 전송
      이때 Close 프레임에는 종료 코드 (Close Code)라는 종료의 이유를 나타내는 2바이트 정수 코드 (예: 1000은 정상적인 종료를 의미)와 종료 이유 (Reason)라는 UTF-8로 인코딩된 종료 사유에 대한 선택적 설명 문자열이 포함된다.
    • 상대방이 Close 프레임을 수신한 후, 해당 종료 요청을 수락하고 응답으로 또 다른 Close 프레임을 전송
    • 두 번째 Close 프레임을 수신한 쪽은 이제 연결을 종료할 수 있다. 이 단계에서 클라이언트와 서버는 모든 리소스를 정리하고 연결을 완전히 닫습니다.

Message와 Frame 웹소켓 프로토콜의 데이터 기본 단위

WebSocket Protocol을 기반으로 데이터를 주고받는 과정에서 주고받는 데이터의 기본 단위는?

바로 Message이다.

메시지(Message)

  • WebSocket을 통해 클라이언트와 서버 간에 주고받는 데이터는 "메시지(Message)" 단위로 처리된다. 이 메시지는 텍스트 또는 바이너리 형태일 수 있다.
    → 텍스트 메시지: 일반적으로 UTF-8로 인코딩된 문자열 데이터
    → 바이너리 메시지: 인코딩 없이 이진 데이터가 그대로 ArrayBuffer 또는 Blob 형태로 전달된다.

Frame(프레임)

  • WebSocket 메시지는 내부적으로 프레임(Frame)으로 나누어져 전송된다. 프레임은 WebSocket 연결을 통해 전달되는 더 작은 데이터 단위이다.
  • 즉, 메시지는 여러 프레임으로 분할될 수 있으며, 하나의 메시지는 여러 프레임으로 전송되었다가 다시 결합된다.
  • 예를 들어, 긴 텍스트 메시지는 여러 프레임으로 나뉘어 전송될 수 있고, 서버나 클라이언트는 이를 재조합하여 하나의 완전한 메시지로 처리한다.
  • '작은' 헤더 + payload로 구성
     헤더: 프레임의 시작을 알리고, 데이터의 끝을 정의하며, 데이터의 성격을 설명하는 정보를 담고 있다. 헤더의 크기(2바이트)가 작아서, HTTP 통신보다 오버헤드가 작다.
     Payload: 전송하고자 하는 실제 데이터(텍스트 또는 바이너리)입니다. 이 데이터는 메시지를 구성하는 일부일 수 있다.

WebSocket 프레임 구조를 활용한 "Hello" 전송 예시

  1. 텍스트 메시지이므로 UTF-8로 인코딩된 데이터를 페이로드에 담는다.
    • "Hello"라는 문자열을 UTF-8로 인코딩하면:
      "Hello"48 65 6C 6C 6F (Hexadecimal 값)
  2. 프레임 헤더를 추가하여 전송하게 된다.
    WebSocket 프로토콜의 표준 헤더 구조는 다음과 같다.
    • FIN: 1 (이 프레임이 메시지의 마지막 프레임임을 나타냄) → 메시지 크기가 커서 여러 프레임으로 나눠지는 경우
    • Opcode: 1 (텍스트 메시지를 나타냄) → 예: 0x1 = 텍스트 메시지, 0x2 = 바이너리 메시지
    • Payload Length: 5 (전송할 데이터의 크기, "Hello"의 길이가 5이므로)
    • Masking Key: 클라이언트에서 전송하는 모든 데이터는 마스킹되어야 하므로 마스킹 키가 포함됩니다. (랜덤한 4바이트 값, 예시로 AA BB CC DD 사용)
  3. 마스킹된 페이로드 계산:
    • 실제로 전송되는 데이터는 클라이언트에서 마스킹 키로 페이로드를 XOR 연산하여 마스킹한 값입니다.
    • 마스킹된 페이로드 계산:
      • H (0x48) XOR AA = E2
      • e (0x65) XOR BB = DE
      • l (0x6C) XOR CC = A0
      • l (0x6C) XOR DD = A1
      • o (0x6F) XOR AA = C5
    그래서 마스킹된 페이로드는: E2 DE A0 A1 C5

최종적으로, '81 05 AA BB CC DD E2 DE A0 A1 C5'

  1. FIN + Opcode: 1000 0001 (FIN = 1, Opcode = 1 for text frame) - Hex: 81
  2. Payload Length: 5 (Hello의 길이) - Hex: 05
  3. Masking Key: AA BB CC DD - Hex: AA BB CC DD
  4. 마스킹된 페이로드 - E2 DE A0 A1 C5

이렇게 "Hello"라는 텍스트 메시지는 WebSocket 프레임으로 만들어져 전송된다. 서버는 마스킹 키를 사용하여 원래의 메시지를 복원한다.

  • E2 XOR AA = 48 (H)
  • DE XOR BB = 65 (e)
  • A0 XOR CC = 6C (l)
  • A1 XOR DD = 6C (l)
  • C5 XOR AA = 6F (o)

복원된 메시지는 "Hello"이다.


WebSocket과 TCP Socket 그리고 UDP Socket과의 차이점

처음 소켓 통신을 거쳐서 웹소켓을 공부하면서 계속 궁금했던 부분을 정리한 유투브가 있어서 보고 정리할 수 있었다.

  • 이 둘은 속한 OSI 7계층이 다르다.
  • TCP Socket 및 UDP Socket은 전송 계층(Transport Layer)인 Layer4에서, WebSocket은 응용 계층(Application Layer)인 Layer7에서 동작한다.
  • 이때 WebSocket은 TCP Socket을 기반으로 동작한다.
    즉, 데이터의 신뢰성과 순서가 보장되는 것이다.

 

 

웹소켓의 한계

  1. 웹소켓은 HTML5부터 지원하는데 이전 기술로 구현되었다면? Socket.io와 Socket.js을 통해 웹 소켓처럼 사용할 수 있도록 도와준다.
  2. 문자열을 주고 받을 뿐 그 이상의 일은 하지 않아 주고 받은 문자열 해독은 어플리케이션이하는데 HTTP와 달리 WebSocket은 형식이 없어 해석하기 힘들다. ➜ 따라서 sub-protocols를 통해 주고 받는 메세지의 형식 약속  STOMP 필요(다음 게시글)
  3. 만약 이러한 WebSocket Protocol을 사용한다면 로드밸런싱을 할때 주의해야한다.