Web Socket 정리
용도
서버와 클라이언트 간 양방향 통신을 지원하기 위해 만들어짐
기존 Real-time 통신에 사용하던 polling, long-polling, streaming 모두가 한계점을 가지고 있어 필요해짐
polling : real-time 통신에서는 언제 통신이 발생할지 예측이 불가능하여 불필요한 request와 connection을 만듬
long-polling : 용량이 큰 메세지를 주고받게 되면 polling에 비해 결국 개선점이 없음. 또한 많은 양의 메세지가 쏟아질 경우 제어가 불가능.
streaming : HTTP의 특징상, 방화벽이나 프록시 서버가 사이에 끼어들게 되면 불필요하게 response를 buffer하여 메세지 전송 시간이 길어지는 문제가 있음. TLS를 쓰면 이러한 문제는 해결할 수 있으나 각각의 커넥션에 드는 비용이 커지는 한계가 존재
결과적으로 이 모든 방법이 HTTP를 통해 통신하기 때문에 Request, Response 둘다 Header가 불필요하게 큼.
작동 방식
생성
WebSocket(URL[, Protocols])
URL은 연결 대상 URL
Protocols는 String 내지는 Array으로 각각 element에 해당하는 subprotocol을 생성.
실질적으로 connection 을 생성하는 것은 비동기적으로 진행
readyState
CONNECTING (0) - connection이 아직 성립되지 못함
OPEN (1) - connection이 성립됨. communication 가능.
CLOSING (2) - close() 메소드가 불려지거나 closing handshake 진행중
CLOSED (3) - connection이 닫혔거나 열리지 않았음.
연결 (Handshake)
Client Request
Server Response
전송
순서
readyState === OPEN 체크.
WebSocket Message 전송.
전송에 실패했는데 buffer가 꽉찬거면 WebSocket as full flag를 세우고 connection 닫기.
메세지 크기만큼 bufferedAmonut에 더하기.
Message, Frame
Message
여러 frame이 모여서 구성하는 하나의 논리적 메세지 단위
Frame
communication에서 가장 작은 단위의 데이터.
2 ~ 14 bytes header + payload
bufferedAmount
send()에 의해 호출되었으나 아직 네트워크로 전송되지 못한 데이터의 크기를 기록
binaryType
blob
디스크에 저장
arrayBuffer
메모리에 저장
이벤트
type
handler
open
onopen
message
onmessage
error
onerror
close
onclose
종료
WebSocket closing handshake 시작. readyState CLOSING으로 변경
깨끗하게 종료되었으면 readyState CLOSED으로 변경
에러가 있었으면 error 이벤트 생성
문제가 없었다면 close 이벤트 생성
고려 사항
웹소켓을 사용할 때 발생가능한 overhead
웹소켓을 사용하면 데이터를 전송할 때 overhead를 최소화시키는게 가능
그러나 브라우저 캐시를 이용할 수 없어서 경우에 따라 요청 빈도가 증가하여 오히려 더 큰 트래픽을 유발할 수 있음
구조에 CDN과 같은 중간 배포 단계들을 포함시키기 힘듬
Long-live web socket connection을 위해 고려해야될 사항
서버측 네트워크의 라우터, 로드밸런서, 프록시 등
기본적으로 대부분의 웹서버와 로드밸런서 등은 HTTP에 최적화되어있고, 그에 따라 timeout이 아주 짧은 편
데이터 흐름을 따라 내 제어하에 있는 모든 단계의 설정에서 timeout을 길게 수정
물론, 각각 connection은 모든 단계의 자원을 추가로 소비하기 때문에 보안, 자원 절약, 예방적 차원에서 짧은 timeout이 옳을 수도 있음.
ISP, carrier 등 외부 네트워크 프록시
WSS TLS 사용
클라이언트측 라우터, 방화벽, 프록시 등
경우에 따라선 web socket을 완전히 사용할 수 없는 때도 있으므로 fallback strategy 필요
성능 체크리스트
신뢰성 있는 데이터 전달을 위해 Secure Websocket(WSS over TLS)을 사용하라
가능한한 polyfill 성능을 위해 주의를 기울여라
application protocol을 만들 때, subprotocol negotiation을 활용하라
binary payload를 최적화하여 전송 크기를 최소화하라
UTF-8 데이터는 암호화하여 전송 크기를 최소화하라
전달받은 binary payload에 올바른 binary type을 지정하라
클라이언트에 buffer된 데이터 양을 모니터링하라
head-of-line blocking을 피하기 위해 큰 메세지는 분할하라
적용가능한 전송 수단을 활용하라
Last updated