본문으로 건너뛰기

· 약 5분

웹소켓​

단일 TCP 연결을 통해 클라이언트와 서버 간 전이중 양방향 통신을 지원하는 프로토콜
웹 환경에서 연속된 데이터를 실시간으로 처리할 수 있다.

웹소켓은 HTTP의 포트를 그대로 사용하고 각각 포트 80과 포트 443을 사용하여 HTTP(ws://) 및 HTTPS(wss://)로 서버에 연결한다.

웹소켓 등장 배경​

웹소켓이 등장하기 이전, 실시간성을 보장하기 위해 Polling, Long polling, Streaming 같은 기술을 사용했어야 했다.
이는 실시간성이나 양방향성을 만족시키지 못했고, HTTP를 이용하기 때문에 과도한 오버헤드가 발생했다.

polling, long polling, streaming

Polling: 주기적으로 서버에 요청을 보내 수신할 정보가 있는지 확인하는 방법

  • 서버에서 보낼 내용이 없어도 클라이언트는 알 수 없다.
  • 계속해서 요청을 보내 확인을 해야하기 때문에 서버에 불필요한 부하를 주어야 한다.

Long Polling: 클라이언트의 요청에 대해 응답을 보내지 않고 있다가 이벤트가 발생했을때 응답하는 방법

  • 폴링 방식보다 서버에 적은 부하를 줄 수 있지만, 요청의 주기가 짧으면 폴링과 차이가 없어진다.

Streaming: 클라이언트가 request를 보내면 커넥션을 맺고, 이 커넥션을 유지하면서 서버가 계속 데이터를 보내는 방법

  • 클라이언트가 서버에 요청을 하고 싶다면 새로운 커넥션을 맺어야 한다.

웹소켓의 동작​

1. Upgrade 요청​

WebSocket 프로토콜로 전환하는 HTTP 요청을 보낸다.
이는 HTTP와 같이 80, 443 포트를 사용한다.
웹소켓으로 전환하기 위해서는 Upgrade: websocket, Connection: Upgrade 헤더가 필요하다.
Sec-WebSocket-Key는 서버에서 Sec-WebSocket-Accept를 계산하여 응답하고 이 값이 예상한 값과 다르면 연결이 수립되지 않는다.
Sec-WebSocket-Protocol의 경우 서브프로토콜의 목록으로 서버 측에서는 해당 목록 중 하나를 선택하여 반환해야 한다.
만약 서버측에서 여러 개 지원이 가능한 경우 지원 가능한 프로토콜 중 첫번째 프로토콜을 클라이언트측으로 보낸다.

GET /chats HTTP/1.1
Host: localhost:8080
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==
Sec-WebSocket-Protocol: v10.stomp, v11.stomp
Sec-WebSocket-Version: 13
Origin: http://localhost:8080

2. Switching Protocols​

서버는 101 Switching Protocols 응답을 반환한다.
Sec-WebSocket-Accept은 Sec-WebSocket-Key 뒤에 258EAFA5-E914-47DA-95CA-C5AB0DC85B11를 붙이고 SHA1로 해싱 후 Base64로 인코딩하여 반환한다.
이는 서버 웹소켓 프로토콜의 지원 여부를 클라이언트에게 명확히 알리기 위해 존재한다.

HTTP/1.1 101 Switching Protocols 
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=
Sec-WebSocket-Protocol: v10.stomp

3. 통신 후 종료​

연결이 수립되면 웹소켓 프레임 단위로 양방향 통신을 한다.
연결 종료를 원하는 경우 클라이언트, 서버 모두 연결 종료를 요청할 수 있다.

참고 자료​

https://datatracker.ietf.org/doc/html/rfc6455
https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications
https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers
https://docs.spring.io/spring-framework/reference/web/websocket.html