WebSocket 완전 정복 · 1부. 기초 · 16편 중 3편
이전 편: 2편 — 프로토콜 개요
2편의 생애주기에서 첫 단계였던 핸드셰이크를 줄 단위로 읽습니다. 클라이언트가 보내는 Upgrade 요청, 서버의 101 응답, 그리고 Sec-WebSocket-Accept가 어떻게 계산되는지까지입니다.
클라이언트 요청 — Upgrade 핸드셰이크
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Origin: https://example.com
Sec-WebSocket-Protocol: chat.v1서버 응답 — 101 Switching Protocols
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat.v1Sec-WebSocket-Accept는 어떻게 만들어지는가
Sec-WebSocket-Accept = Base64( SHA-1( 클라이언트 키 + 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 ) )
import { createHash } from "node:crypto";
const GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
function acceptKey(key: string) {
return createHash("sha1").update(key + GUID).digest("base64");
}
acceptKey("dGhlIHNhbXBsZSBub25jZQ=="); // "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="이 절차는 보안 장치가 아니다
이 절차는 보안용이 아닙니다. 상대가 정말 WebSocket을 이해하는 서버인지 확인하고, HTTP 캐시가 응답을 재사용하지 못하게 하는 장치입니다. 인증은 별도로 해야 합니다(10편 — 인증과 인가).
101 이후, 이 연결은 더 이상 HTTP가 아니다
101 응답 이후 이 TCP 연결은 더 이상 HTTP가 아닙니다. 이 사실이 프록시·로드밸런서 문제의 근원입니다.
중간 장비가 구체적으로 어디서 이 연결을 끊고 무엇을 설정해야 하는지는 14편 — 인프라: Nginx, 로드밸런서, 그리고 OS 한계에서 다룹니다.
더 깊이
- 풀스택 개발자를 위한 네트워크 6장 — HTTP: 웹의 언어와 그 진화: Upgrade 이전까지의 HTTP 요청·응답 구조입니다. 위의 핸드셰이크가 왜 GET 요청과 상태 줄의 모양을 하고 있는지가 여기서 옵니다.