WebSocket 핸드셰이크, 프레이밍, 연결 수명주기

WebSocket은 클라이언트와 서버가 하나의 연결에서 양방향 메시지를 주고받도록 하는 프로토콜입니다. RFC 6455는 HTTP/1.1 Upgrade 핸드셰이크 이후 TCP 위에서 프레임을 주고받는 방식을 정의합니다. 브라우저는 스크립트의 출처를 Origin으로 보내며 서버는 이를 검토할 수 있지만, Origin 값만으로 사용자 인증이나 권한 부여가 되는 것은 아닙니다. 브라우저 API가 보내는 클라이언트 프레임은 마스킹되고, 프레임은 텍스트·바이너리 메시지 또는 제어 프레임의 일부가 될 수 있습니다. 메시지 프레임 경계를 애플리케이션의 영구 메시지·재생 경계로 오해하지 마세요.

전문가 관점: 지속 연결도 끊어지고 다시 연결됨

Cloudflare 네트워크 문서는 Cloudflare 프록시와 로드밸런서 환경에서 유휴 WebSocket을 닫을 수 있으며, 재연결은 다른 origin으로 갈 수 있어 세션 친화성이 필요할 수 있다고 설명합니다. 이는 해당 사업자의 배포 동작이지 모든 WebSocket 서버의 시간 제한을 뜻하지 않습니다. RFC도 재연결이나 메시지 저장·복구를 제공하지 않습니다. 서버 재배포, 모바일 네트워크 전환, 프록시 timeout 등으로 연결은 끊길 수 있습니다. heartbeat는 중간 장비의 idle 감지에 도움을 줄 수 있지만 연결 생존이나 메시지 전달을 보장하지 않으며, 양측 timeout보다 적절히 짧게 설정해야 합니다.

WebSocket은 애플리케이션 의미를 정의하지 않음

프로토콜은 메시지 framing, control ping/pong, close handshake를 정의하지만 업무 이벤트의 스키마, 순서 보장 범위, 재전송, 중복 제거, 권한 정책은 애플리케이션 책임입니다. 한 TCP 연결 안에서는 바이트 순서가 있지만, 재연결 뒤의 논리 메시지 순서나 중복 방지는 별도 sequence ID와 acknowledgement가 필요합니다. 압축 확장 사용은 메모리·CPU 및 압축 관련 위험을 검토해야 합니다. 메시지 크기와 연결당 버퍼를 제한하고, 수신 속도보다 생산 속도가 빠를 때의 backpressure 정책을 구현하세요.

보안·확장성·테스트 조건

wss:는 TLS로 전송 구간을 보호하지만 메시지 권한 검사와 입력 검증을 대체하지 않습니다. 브라우저 연결에서는 허용 Origin을 서버가 검증하고, 쿠키 기반 인증이면 cross-site WebSocket hijacking을 고려해야 합니다. 인증정보와 세션 만료, 연결별 구독 권한도 재검증해야 합니다. 장기 연결은 일반 HTTP 요청처럼 매번 새로 분산되는 것이 아니므로 접속 시점의 로드밸런싱, 연결 수·파일 디스크립터·메모리 비용, 서버 종료 시 drain, 재접속 폭주를 운영에 반영하세요. Cloudflare의 idle 동작과 affinity는 해당 제품 경로에만 적용됩니다. 실제 CDN·프록시·origin 조합에서 유휴 유지, ping/pong, 대용량 메시지, 장애 후 재연결을 시험하세요.

참고 자료