본문 바로가기

네트워크

WebSocket과 친해지기

들어가면서

서버와 실시간으로 데이터를 주고받는 서비스를 개발하는 데 필요한 WebSocket!

이번 글을 통해 WebSocket 개념을 정리하겠다.

 

WebSocket

WebSocket은 뭘까? RFC 6455에 따르면 다음과 같이 나와 있다.

The WebSocket Protocol enables two-way communication between a client running untrusted code in a controlled environment to a remote host that has opted-in to communications from that code. The security model used for this is the origin-based security model commonly used by web browsers. The protocol consists of an opening handshake followed by basic message framing, layered over TCP. The goal of this technology is to provide a mechanism for browser-based applications that need two-way communication with servers that does not rely on opening multiple HTTP connections (e.g., using XMLHttpRequest or <iframe>s and long polling).

WebSocket Protocol은 Client와 Server의 양방향 통신을 가능하게 해주는 Protocol이다. 기존 양방향 통신을 가능하게 한 기법들은 HTTP connection을 여러 번 수행해야 했는데, 이는 효율적이지 않아 이를 해결하기 위해 등장했다. 

 

그렇다면 옛날에는 어떤 방식을 사용했고, 어떤 문제가 있어 WebSocket Protocol이 등장했을까?

 

WebSocket의 역사

WebSocket Protocol이 등장하기 전에는 Client와 Server 간 양방향 통신을 위해 여러 HTTP 요청/응답을 이용했다. 이 방법들은 비효율적이어서 WebSocket Protocol이 등장했다.

 

양방향 통신을 위한 대표적인 3가지 기법.

1. Polling

2. Long Polling

3. Streaming

 

Polling

Polling 방식은 Client가 Server에 일정한 주기를 갖고 요청과 응답을 주고 받는 기법이다. 

 

Polling

 

Polling 방식으로 양방향 소통을 하려면 요청 주기를 매우 짧게 해야 한다. 이는 Server에 많은 부하를 준다. 또한 HTTP는 Header가 무거운 Protocol이기 때문에 잦은 데이터 송수신에 효율적이지 않다.

 

Long Polling

Long Polling은 Polling 방식에서 너무 많은 HTTP 요청/응답이 필요한 문제를 해결하기 위해 나온 기법이다.

Long Polling은 Client가 Server에 요청을 보낼 때 Server가 바로 응답하지 않는다. Server는 연결만 유지하고 특정 Event가 발생하거나, Time-Out이 발생하면 Client에 응답한다. Client는 Server에서 응답을 받고 다시 HTTP 요청을 보낸다.

 

Long Polling

 

Long Polling 방식을 이용한 양방향 소통은 Pooling 방식보다 효율적이다. 하지만 이 방식도 여전히 HTTP 요청을 적지 않게 사용해야 한다.

 

Streaming

Streaming 방식을 사용하면 Long Polling보다 더 적은 HTTP 요청/응답으로 양방향 소통할 수 있다.

Streaming 방식은 Client가 Server에 HTTP 요청을 보내고, Server가 특정 이벤트가 발생했을 때 응답한다. 이는 Long Polling과 유사하다. 차이점은 Streaming 방식은 Server가 Client에 응답을 보내주고 연결을 끊지 않는다. 즉, Client가 Server에 다시 HTTP 요청을 할 필요가 없다.

 

Streaming

 

Streaming 방식을 사용한 양방향 소통은 더 적은 HTTP 요청/응답이 필요하다. 하지만 연결을 계속 유지해야 한다는 단점과 데이터 송 수신을 위해 무거운 HTTP 메시지를 사용해야 한다는 문제는 남아있다.

 

 

HTTP를 사용해도 Client와 Server 간 양방향 소통을 할 수 있지만, 아쉬움이 남아있다. 이를 WebSocket Protocol을 활용하면 해결할 수 있다. WebSocket Protocol에 대해 좀 더 깊이 알아보자.

 

WebSocket Digging

The protocol has two parts: a handshake and the data transfer.

WebSocket Protocol은 Handshake와 Data Transfer 두 부분으로 나눌 수 있다.

 

websocket

 

Handshake

Handshake는 Opening Handshake와 Closing Handshake로 나눌 수 있다.

 

Opening Handshake

Opening Handshake는 Client와 Server가 연결하기 위한 첫 단계다. Opening Handshake는 HTTP 요청을 통해 이루어지고 성공하면 WebSocket Protocol로 Data 전송이 이뤄진다.

 

Client가 Server에 HTTP를 이용해 연결 요청을 보낸 후, Server가 연결 허용 HTTP 응답을 보내면 WebSocket Protocol을 통해 Client와 Server 간 양방향 소통이 가능하다.

 

Client가 보내는 HTTP Header는 다음과 같다.

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

Upgrade: websocket, Connection: Upgrade 

Server에 Websocket Opening Handshake HTTP 요청임을 알려준다.

 

Sec-WebSocket-Key

Server에서 Client에 Handshake 요청을 받았음을 증명하기 위해 Sec-WebSocket-Accept를 응답한다. 이 값을 만들 때 사용한다.

 

Sec-WebSocket-Protocol : chat, superchat

Client에서 사용가능한 sub-protocol 리스트를 Server에 알려준다. Server는 값 중 하나를 선택하거나 선택하지 않고, 그 결과를 Client에 알려준다.

 

Server가 응답하는 HTTP Header는 다음과 같다.

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

HTTP/1.1 101 Switching Protocols

연결이 성공해, HTTP에서 WebSocket Protocol로 전환되었다는 응답코드다.

 

Sec-WebSocket-Accept

Client에 Handshake 요청을 잘 받았음을 증명해주는 값이다.

 

Closing Handshake

Closing Handshake는 간단하다.

Client와 Server 둘 중 한 곳에서 연결을 종료한다는 frame을 보내면 다른 한쪽도 응답을 보내고 연결이 종료된다.

 

Data Transfer

Data Transfer에서 데이터는 Message라는 논리적 단위로 전송된다. 

 

Message는 여러 Frame들이 모여 구성된다.

 

Frame은 작은 헤더와 payload로 구성되어 있다. HTTP와 비교해 메타 데이터양이 적어 데이터를 더 효율적으로 송수신할 수 있다. 쉽게 말하면 HTTP는 TCP에서 사용하는 Frame에 많은 부가 정보를 추가하지만, WebSocket Protocol은 최소한의 부가 정보만 추가한다.

 

추가로 한 가지 재미난 사실이 있다. RFC 6455를 살펴보면 다음과 같이 나와 있다.

a client MUST mask all frames that it sends to the server (see Section 5.3 for further details). (Note that masking is done whether or not the WebSocket Protocol is running over TLS.)
...
A server MUST NOT mask any frames that it sends to the client.

네트워크상에 있는 중재자(예시 - 프록시)와 보안상의 이유로 Client에서 Server로 Frame을 보낼 때는 무조건 Frame을 마스킹하고, Server에서 Client에 Frame을 보낼 때는 마스킹하지 않는다고 한다.

 

정리

지금까지 WebSocket Protocol이 나오게 된 배경과 기술에 대해 알아봤다. 

간략하게 정리하자면 WebSocket Protocol은 Client와 Server의 양방향 소통을 위해 여러 HTTP 메시지를 이용하는 기법들을 대체하기 위해 등장했다.

WebSocket Protocol은 크게 Handshake와 Data transfer로 나눌 수 있다. Opening Handshake는 HTTP를 통해 이뤄진다. 연결된 후에는 메시지를 단위로 데이터를 송수신하는데, 이는 HTTP의 메시지보다 데이터양이 적어 효율적이다.

 

좀 더 자세한 내용을 알고 싶다면, RFC 6455를 읽어보길 추천한다.

 

reference

https://datatracker.ietf.org/doc/html/rfc6455

 

RFC 6455: The WebSocket Protocol

The WebSocket Protocol enables two-way communication between a client running untrusted code in a controlled environment to a remote host that has opted-in to communications from that code. The security model used for this is the origin-based security mode

datatracker.ietf.org

https://doozi0316.tistory.com/entry/WebSocket%EC%9D%B4%EB%9E%80-%EA%B0%9C%EB%85%90%EA%B3%BC-%EB%8F%99%EC%9E%91-%EA%B3%BC%EC%A0%95-socketio-Polling-Streaming

'네트워크' 카테고리의 다른 글

HTTP Connection 역사 알아보기  (0) 2024.02.24
SSE(Server Sent Event) 개념 정리  (0) 2024.02.15
HTTPS 적용 방법과 동작원리  (1) 2023.07.14
REST API  (0) 2022.06.14