WebSocket

Parker.Park·2022년 8월 17일
0

개념

목록 보기
10/16

WebSocket?

기존 HTTP 프로토콜은 요청과 응답으로 통신을 하는 것이다. 그러나 언제부턴가 웹에서는 채팅과 같은 실시간 통신이 가능하다는 것을 경험하였다. 어떻게 양방향 통신이 가능했는지에 대해서 정리해보고, HTML5 부터 표준이 된 WebSocket 프로토콜에대해서 알아보자.

HTTP의 한계

HTTP 프로토콜은 가장 성공적이 프로토콜이라 한다. 하지만 인터넷이 발달하면서 점차 사람들은 더 많은것을 원하기 시작하였다. 채팅과 같은 지속적인 양방향 통신말이다. 하지만 HTTP프로토콜은 클라이언트에서 먼저 요청을 보내야만 그에 대한 응답을 받을 수 있기 때문에 연결이 유지되는 것은 불가능하다고 볼 수 있다.
그렇게해서 연결을 유지하는 WebSocket이 아닌 우선 비슷한 효과를 내는 HTTP 방식인 Polling, Long Polling, Streaming에 대해서 알아보자.

Polling

클라이언트에서 일정 주기마다 요청을 보내고 서버는 현재 상태를 바로 응답하는 방식이라고 한다. 이 방식은 실시간으로 반영되는 것이 중요한 서비스에는 좋지 않고, 서버에서 변화가 없더라도 매 요청마다 응답을 내려주기 때문에 불필요한 트래픽이 발생한다고 한다.

Long polling

클라이언트에서 요청을 보내고 서버에서 이벤트가 발생했을 때 응답을 내려주고, 클라이언트는 응답을 받고 다시 다음 응답을 기다리는 요청을 보내는 방식이라고 한다. 실시간 반응이 가능하고 polling에 비해서 불필요한 트래픽은 유발하지 않지만 이벤트가 잦아지면 과부하가 발생한다.

Streaming

이벤트가 발생했을때 응답을 내려주는데 응답을 완료시키지 않고 계속 연결을 유지하는 방식이라고 한다.
Long Polling에 비해 응답마다 다시 요청하지 않아도 되므로 효율적이지만, 클라이언트에서 서버로의 데이터 송신이 어렵고, 연결 시간이 길어질 수록 연결의 유효성 관리의 부담이 발생한다고 한다.

위 3가지 방법으로 양방향 통신을 구현하였으나 HTML5에 들어서 websoket 프로토콜이 표준으로 등록되어 이를 이용하여 서버-클라이언트간의 양방향 통신을 구현 할 수도 있게 되었다고 한다.

websocket 연결

웹소켓 프로토콜로 연결하기 위에서는 http or https 프로토로로 요청과 응답을 통해 연결하게 된다. 이것을 핸드 쉐이킹이라고 한다. websocket 연결 요청 예시에 대해 정리해보자.

websocket 요청시 http request 헤더 예시

GET /chat HTTP/1.1
Host: backend.abc.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhJHNhDL1BsLkh25BhXZQ==
Origin: http://abc.com
Sec-WebSocket-Protocol: chat, soap
Sec-WebSocket-Version: 1
  • GET /chat HTTP/1.1
    Get 메서드로 요청 해야하며 HTTP 버전은 1.1 이상을 의미한다.

  • Host: backend.abc.com
    웹 서버 주소

  • Upgrade: websocket
    현재 프로토콜에서 websocket 프로토콜로 업그레이드, 즉 변경을 의미한다.

  • Connection: Upgrade
    Upgrade 헤더 필드가 명시 되어 있을 경우, 송신자는 반드시 Upgrade 옵션을 지정하여 헤더에 포함하여야 한다.

  • Sec-WebSocket-Key: dGhJHNhDL1BsLkh25BhXZQ==
    Sec-WebSocket-Key로 클라이언트와 서버간에 서로를 인증한다.

  • Origin: http://abc.com
    클라이언트 주소

  • Sec-WebSocket-Protocol: chat, soap
    서브 프로토콜이라고 저렇게 여러개 보낼 수 있다고 하는데, 서버에서는 서브프로토콜중 하나만 보내거나 지원하지 않을 경우 프로토콜을 헤더에서 지워서 보내야 한다.(MDN 웹소켓 서버 작성하기 - 서브프로토콜 중)

    다음은 응답에 대한 예시이다.

 websocket 응답시 http request 헤더 예시
 
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: e3prc0sMlxakAGmmQ9PpG2HaxOo=
Sec-WebSocket-Protocol: chat
  • HTTP/1.1 101 Switching Protocols
    웹소켓이 연결되었다는 의미이다.
  • Sec-WebSocket-Accept: e3prc0sMlxakAGmmQ9PpG2HaxOo=
    클라이언트로 부터 받은 Sec-WebSocket-Key를 사용하여 계산된 값이다. 이 값을 통해 클라이언트는 정상적인 핸드쉐이크 과정을 검증한다고 한다.

데이터 전송

핸드 쉐이크가 끝나면 http/https프로토콜에서 ws/wss프로토콜로 변경된다. ws/wss 프로토콜도 http/https 프로토콜과 같이 SSL 적용이 가능하다고 한다. 이제 서로 통신을 해야하는 Message단위로 커뮤니케이션을 하는데, 이것은 한개 이상의 frame으로 이루어져 있다.

데이터 프레임 포맷

frame은 통신의 가장작은 데이터 단위라고 한다. 작은 헤더와 payload를 포함한다고 한다. 여기서 작은 헤더는 http/https 헤더에 비교하여 작기 때문이다. 그만큼 양방향 통신을 가볍게 하기위함이라고 생각한다.

 0               1               2               3
 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len |    Extended payload length    |
|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
|N|V|V|V|       |S|             |   (if payload len==126/127)   |
| |1|2|3|       |K|             |                               |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
 4               5               6               7
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|     Extended payload length continued, if payload len == 127  |
+ - - - - - - - - - - - - - - - +-------------------------------+
 8               9               10              11
+ - - - - - - - - - - - - - - - +-------------------------------+
|                               |Masking-key, if MASK set to 1  |
+-------------------------------+-------------------------------+
 12              13              14              15
+-------------------------------+-------------------------------+
| Masking-key (continued)       |          Payload Data         |
+-------------------------------- - - - - - - - - - - - - - - - +
:                     Payload Data continued ...                :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|                     Payload Data continued ...                |
+---------------------------------------------------------------+

위는 frame header를 비트순으로 표현한것이다. 0비트 부터 정리하자면 아래와 같다.

  • FIN
    메시지의 frame중 마지막 frame인지 나타내는 값이다. 0일 경우 서버는 뒤에 더 따라오게 될 메시지들까지 수신해야 하고, 1일 경우 전체 메세지가 수신된 것으로 처리한다.
  • RSV1~3
    사용되는 않는 비트이며, 확장 프로토콜 또는 미래를 위해 예약한 비트이다.
    -OPcode(4bits)
    뒤따라오는 payload데이터가 어떠한 포맷인지 나타낸다고 한다. 총 4bit를 할애하기 떄문에 의미는 다음과 같다.
    - 0x0 : continuation
    • 0x1 : 텍스트(UTF-8)
    • 0x2 : 바이터리 테이터
    • 0x3 ~ 7 : Reserved for further non-control frames
      - 0x8 : Close 핸드쉐이크를 시작
    • 0x9 : Ping
    • 0x10 : Pong
    • 0x11~15 : Reserved for further non-control frames
  • MASK
    MASK 비트는 메세지가 인코딩되어 있는지 여부를 나타낸다고 한다. proxy cache poisoning attacks를 방지하기 위한 방법이라고 한다.
    클라이언트가 서버에 보내는 메시지는 항상 마스킹 되어야 하기 때문에 이 필드는 1임을 기대할 수 있다. 반대로 서버에서 클라이언트로 보내는 메세지는 MASK 필드가 항상 0이고 데이터는 마스킹 되지 않은 상태라고 한다.
    MASK 비트가 1이 세팅되어 있다면 payload데이터에 마스크로 4바이트(32비트)가 설정된다고 한다. 이 필드를 Masking-key필드라고 한다. ENCODED 값과 Masking-key 값으로 XOR연산을 수행하여 DECODED값이 나온다고 하는데 잘 이해가 되지 않는 부분이다 ㅠ.
  • payload lenth
    payload 데이터를 읽기 위해서는 payload length를 읽어야 한다고 한다. 9~15번째 비트를 읽고 이를 unsigned integer로 취급한다고 한다. 이 값이 125보다 작을경우 이 자체가 payload length가 된다. 값이 126이면 다음 16비트를 읽고 같은 방식으로 unsigned integer로 취급하고 payload length값으로 사용한다. 127일 경우 다음 64비트를 읽는다고 한다. 처리방식은 이전 처리방식과 똑같다.

WebSocket 프로토콜 특징

  • 최초 접속 시작시에는 http프로토콜 위에서 handshakingㅇ르 하기 때문에 http header를 사용.
  • 웹소켓은 별도의 포트가 없으며, 기존 http포트인 80, 443을 사용
  • 프레임으로 구성된 메시지라는 논리적 단위로 송수신

WebSocket 프로토콜 한계

  • HTML5이전 기술로 구현되었기 때문에 이전 환경에서는 지원이 안된다.
    Socket.io, SockJS와 같은 서비스가 웹 소켓처럼 사용할 수 있도록 도와준다.
  • 문자열을 주고받게 해줄 수 있는 역할만으로 한계되어 있다.
    HTTP형식과 달리 WebSocket은 주고받은 문자열의 해독은 온전히 어플리케이션에 따르기 때문이다. 그래서 Subprotocol을 많이 사용한다고 하는데 주로 사용 되는 프로토콜이 STOMP라고 한다.

마치면서

웹소켓에 대해서 간략하게 알아보았다. 다음에는 구현해봐야겠다.

참조

[웹소켓에 대해 알아보자, Tecoble, 2022년08월22일 접속]
https://tecoble.techcourse.co.kr/post/2020-09-20-websocket/

[websocket, socket.io를 이용한 양방향 통신, Zych1751 삼성소프트웨어멤버십 블로그, 2022년08월22일 접속]
http://www.secmem.org/blog/2019/08/17/websocket-socketio/

[[10분 테코톡] 🧲코일의 Web Socket, 우아한Tech, 2022년08월22일 접속]
https://youtu.be/MPQHvwPxDUw

[웹소켓 서버 작성하기, MDN, 2022년08월22일 접속]
https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#%EC%84%9C%EB%B8%8C%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C

[웹소켓 헤더, 프레임 분석 (websocket header, frame),https://alnova2.tistory.com/915 [몽상가:티스토리], 2022년08월22일 접속]
https://alnova2.tistory.com/915

[[Network/OS] Network Socket(IP Socket, WebSocket), https://shinjam.tistory.com/entry/NetworkOS-Network-SocketIP-Socket-WebSocket [잼있는 블로그:티스토리], 2022년08월24일 접속]
https://shinjam.tistory.com/entry/NetworkOS-Network-SocketIP-Socket-WebSocket

[[바미] Web Socket에 대해 알아보자!, https://codesk.tistory.com/, 2022년08월24일 접속]
https://codesk.tistory.com/57

profile
개발자준비중

0개의 댓글