WebSocket 프로토콜의 배경과 핸드셰이크 정리

Dal col·2025년 4월 4일

WebSocket

목록 보기
2/6

WebSocket의 배경

websocket의 이전 양방향 통신은 한계가 뚜렷했습니다.

  • HTTP 폴링 (Polling) : 클라이언트가 요청을 보냈지는 일정 주기마다 확인을 하는 작업으로 항상 불필요한 요청과 응답이 있었습니다.

  • Long Polling : 클라이언트 측에서 요청이 올 때까지 서버는 응답을 지연시키지만 이것 또한 새로운 요청을 보내야 한다는점에서 한계가 있었습니다.

  • 멀티 TCP 연결 : 기존 양방향 통신 방식에서는 클라이언트마다 별도의 TCP를 연결 생성을 하였습니다. 이로인해 서버 부하가 증가하였습니다.

WebSocket의 등장으로 이런 한계점이 개선이 되었습니다.

  • 단 1개의 TCP 연결을 유지하면서 서버와 클라이언트 간의 양방향 통신이 가능해졌습니다.

  • HTTP 요청-응답 모델을 따르지않고 클라이언트와 서버가 자유롭게 데이터를 주고받게되었습니다.

  • 기존 HTTP 인프라(프록시, 필터링, 인증 등)을 활용하면서 효율적인 통신을 제공합니다.

  • HTTP 포트 80(일반 ws://)과 443(보안 wss://)을 사용하여 방화벽 우회를 쉽게 할 수 있습니다.

  • 기존 HTTP와 완전히 다른 프로토콜이지만 핸드셰이크 단계에서는 HTTP를 사용하여 연결을 설정할 수 있습니다.

프로토콜 개요

프로토콜은 핸드셰이크와 데이터 전송의 두 부분으로 구성됩니다.

핸드셰이크는 websocket 연결을 설정하는 초기 과정입니다.

핸드셰이크 시작

클라이언트의 핸드셰이크

 GET /chat HTTP/1.1
        Host: server.example.com
        Upgrade: websocket
        Connection: Upgrade
        Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
        Origin: http://example.com
        Sec-WebSocket-Protocol: chat, superchat
        Sec-WebSocket-Version: 13
  • Host : 해당 주소에서 요청을 보냈다는걸 표시
  • Upgrade : WebSocket으로 변경을 원하는 표시
  • Connection : HTTP에서 WebSocket으로 변경하겠다는 의미
  • Sec-WebSocket-Key : 보안을 위한 키
  • Origin : 클라이언트가 현재 요청을 보낸 웹사이트 출처를 나타냄
  • Sec-WebSocket-Protocol : 사용할려는 프로토콜 지정 (chat, superchat)
  • Sec-WebSocket-Version : WebSocket 버전 (13)

서버의 핸드셰이크

       HTTP/1.1 101 Switching Protocols
       Upgrade: websocket
       Connection: Upgrade
       Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
       Sec-WebSocket-Protocol: chat
  • HTTP/1.1 101 Switching Protocols : 프로토콜을 HTTP에서 WebSocket 프로토콜로 변경 응답
  • Upgrade: websocket : WebSocket 프로토콜로 업그레이드 됐다는걸 표시
  • Connection: Upgrade : HTTP에서 WebSocket으로 변경 승인했다는 의미
  • Sec-WebSocket-Accept: 클라이언트의 Sec-WebSocket-Key를 변환한 값

핸드셰이크 종료

핸드셰이크 종료 과정은 Close 프레임을 사용하여 연결을 닫습니다.
현재 제어 프레임에 대해 정의된 opcode 0x8(닫기), 0x9(핑), 0xA(퐁)를 포함합니다.

종료 과정

  • 클라이언트와 서버 중 한쪽에서 Close 프레임(0x8 닫기)을 전송하면 종료 절차가 시작됩니다.
  • 요청을 받은 곳에서도 Close 프레임을 응답으로 보냅니다.
  • 응답을 받은 요청을 보낸 쪽에서는 TCP 연결을 닫음으로써 WebSocket 연결이 완전히 종료됩니다.

Close 프레임 특징

  • 본문에 종료 이유를 포함할 수 있습니다.

  • 종료 이유는 2바이트 상태 코드와 UTF-8로 인코딩된 데이터가 포함될 수 있습니다.

  • 클라이언트에서 서버로 전송된 닫기 프레임은 다음과 같이 마스킹되어야 합니다.

    마스킹란
    마스킹 키는 클라이언트가 무작위로 선택한 32비트 값입니다.
    클라이언트에서 서버로 보내는 WebSocket 프레임의 페이로드를 변형하여 보안성을 높힙니다.

중요한 규칙

  • Close 프레임을 보낸 후에는 더 이상 데이터 프레임을 전송하면 안됩니다.
  • 양쪽에서 동시에 Close 프레임을 보낼 수 있습니다. (이렇게 시작하는 것이 안전함)

TCP 종료

  • 서버는 즉시 TCP 연결을 닫습니다.
  • 클라이언트는 서버가 닫은 후 기다렸다가 닫습니다.
  • 만약 서버가 적절한 시간 내에 TCP를 닫지않으면 클라이언트는 직접 닫을 수도 있습니다.

상태코드

1000

1000은 정상적인 폐쇄를 나타내며, 이는 다음과 같은 목적을 의미합니다.
연결이 설정되었습니다.

1001

1001은 서버와 같이 엔드포인트가 "사라지고 있음"을 나타냅니다.
페이지가 다운되거나 브라우저가 페이지를 벗어났습니다.

1002

1002는 엔드포인트가 연결을 종료하고 있음을 나타냅니다.
프로토콜 오류로 인해.

1003

1003은 엔드포인트가 연결을 종료하고 있음을 나타냅니다.
수락할 수 없는 데이터 유형(예:
텍스트 데이터만 이해하는 엔드포인트는 이것을 보낼 수 있습니다.
이진 메시지를 수신합니다).

WebSocket에서의 TCP 및 HTTP의 관계

WebSocket은 연결을 위해 초기 핸드셰이크에 HTTP를 사용하지만, 그 이후에는 독립적인 TCP 기반의 통신 프로토콜로 동작합니다.

TCP 관계

WebSocket은 TCP 기반 프로토콜입니다.

TCP는 애플리케이션 간에 안전하게 데이터를 주고받는 것을 보장합니다.

기본 포트로는 두가지가 있습니다.

  • 일반 WebSocket : 80 포트
  • 보안 WebSocket : 443 포트

보안 WebSocket(wss://)은 TLS를 사용하여 데이터를 암호화합니다.
이 과정에서 HTTPS와 마찬가지로 프록시 서버를 통과하기 위해 '터널링 연결'이 사용됩니다.

터널링이란?
네트워크 프로토콜의 데이터를 다른 프로토콜의 포맷으로 감싸 전송하는 방식으로,
주로 TLS 같은 보안 연결을 프록시 서버에서 우회하기 위해 사용됩니다.

HTTP 관계

WebSocket과 HTTP의 관계는 초기 연결 과정에서만 존재합니다.

  • WebSocket은 초반 연결을 위해 HTTP를 사용해 핸드셰이크 요청을 보냅니다.
  • 서버에서 Upgrade를 승인하여 HTTP -> WebSocket으로 전환합니다.

HTTP는 저 과정에서만 사용하고 그 이후로는 WebSocket 프로토콜을 통해 작동합니다.

WebSocket 연결 종료는 HTTP가 아닌, 자체 프로토콜의 Close 프레임을 통해 처리됩니다.

profile
백엔드 개발자가 되기까지의 과정

0개의 댓글