네트워크

채팅 기능 구현을 위한 이론적 공부

iksadnorth 2023. 10. 4. 23:42

👣 개요

단순히 기능 구현만을 위해 인터넷에서 코드 레퍼런스를 찾는 것과
서적 등을 찾아보며 기술의 이론적 배경을 찾고 이후에 코드를 공부하는 것의
퀄리티 차이가 꽤 많이 난다는 것을 깨달은 후에 단순히 코드를 찾는 것은
이 후 기술 적용에는 도움이 되지 않는다는 것을 깨달았다.

때문에 프로젝트에 채팅 기능을 당장 구현하기 이전에
채팅 시스템에 대한 이론적 공부를 수행하고자 한다.

 

👣 WebSocket 이전의 채팅 구현

1. Polling

단순히 HTTP 프로토콜 위에서 작동하는 구현 방법 중 하나다.
특정 주기마다 요청-응답을 수행하며 데이터의 상태를 체크하는 방식으로
리소스 낭비가 매우 심하다. 불필요한 트래픽을 끊임없이 생성할 뿐만 아니라
요청 주기가 크다면 실시간 채팅이란 말이 무색해질 수도 있다.

- 장점:
구현이 매우 쉽다,
일정하게 주기적으로 데이터를 발생시키는 방식에서는 효율적이다.
HTTP 기반이기에 이식성이 좋다,
WebSocket은 Client와의 연결을 유지해야 하기 때문에 서버의 부하를 일정 수준이하로
제한하기 어렵지만 polling은 단순히 특정 주기로 보내는 것을 일시 정지하면 되기 때문에 부하 조절이 쉽다.

- 단점:
불필요한 트래픽을 유발한다.
실시간성이 다른 방식에 비해 좋지 못하다.

2. Long Polling 

마찬 가지로 HTTP 프로토콜 위헤서 작동하는 구현 방법 중 하나다.
특정 주기마다 요청-응답을 클라이언트에서 보내는 것이 아니라
서버에서 데이터가 생성될 때까지 응답을 지연시키다가
채팅에 의해서 메시지 데이터가 생성될 때, 그제서야 유보시켰던
응답을 건네주는 방식을 가지고 있다.
Polling 방식에 비해 실시간성이 아주 좋지만
만약 채팅을 요구하는 Client 갯수가 너무 많으면 서버는 Queue에 너무 많은
요청 대기가 쌓이면서 서버에 무리를 준다.

- 장점:
구현이 매우 쉽다,
HTTP 기반이기에 이식성이 좋다,
Polling 방식에 비히 실시간성이 우수하다.
WebSocket은 Client와의 연결을 유지해야 하기 때문에 서버의 부하를 일정 수준이하로
제한하기 어렵지만 polling은 단순히 특정 주기로 보내는 것을 일시 정지하면 되기 때문에 부하 조절이 쉽다.

- 단점:
채팅을 요구하는 Client 갯수가 너무 많으면 서버는 Queue에 너무 많은
요청 대기가 쌓이면서 서버에 무리를 준다. 많은 Client를 상대하기 어렵다.

3. streaming

Long Polling과 마찬가지로 Client가 최초 연결 시, 연결 요청 Request를 보내고 
서버에서 데이터가 생길 때마다 응답을 주는 방식이다.
다만, Long Polling은 Http 요청-응답 방식을 유지하기 위해 Client에서 응답을 받자마다
다시 Request를 줬다면 Streaming 방식은 단순히 응답만 일방적으로 주는 방식이라고 볼 수 있다.
보통의 HTTP 프로토콜과 다르다고 해서 응답 방식이 HTTP 프로토콜을 따르지 않는다는 것은 아니다.
응답은 HTTP 프로토콜의 응답과 다를 바가 없이 Header를 가지고 있고 Body로 데이터를 전달한다.

- 장점:
Long Polling에 비해 트래픽 소모량이 적게 든다.

- 단점:
역시나 HTTP 프로토콜이기에 불필요한 Header 전송이 요구된다.
양방향 실시간 데이터 전송이 어렵다.

 

👣 WebSocket

양방향 채널을 이용해 채팅방 처럼 양방향 통신이 가능하다.

기존 http요청 응답 방식은 요청한 그 클라이언트에만 응답이 가능했는데,
ws 프로토콜을 통해 웹소켓 포트에 접속해 있는 모든 클라이언트에게 이벤트 방식으로 응답한다

최초 접속이 일반 http request를 통해 handshaking과정을 통해 이루어 지기 떄문에,
기존의 80, 443 포트로 접속을 하므로 추가로 방화벽을 열지 않고도 양방향 통신이 가능하고,
http 규격인 CORS적용이나 인증등의 과정을 기존과 동일하게 가져갈 수 있는것이 장점이다.

단, websocket 프로토콜을 처리하기 위해 전이중 연결과 새로운 웹소켓 서버가 필요하다.
뿐만 아니라 HTTP5 기반으로 작동하는 것이기에 옛 버전의 HTTP를 사용하는 브라우저에서는 작동시키기 어렵다.

 

👣 WebSocket Handshake

위 이미지의 빨간 색 박스에 해당하는 Opening Handshake
위 이미지의 노란 색 박스에 해당하는 Data transfer
위 이미지의 보라 색 박스에 해당하는 Closing Handshake

 

👣  Opening Handshake 요청 헤더

GET /chat HTTP/1.1
Host: localhost:8080
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://localhost:9000

Upgrade
프로토콜을 전환하기 위해 사용하는 헤더.
웹소켓 요청시에는 반스에 websocket 이라는 값을 가지며,
이 값이 없거나 다른 값이면 cross-protocol attack 이라고 간주하여 웹 소켓 접속을 중지시킨다.

Connection
현재의 전송이 완료된 후 네트워크 접속을 유지할 것인가에 대한 정보.
웹 소켓 요청 시에는 반드시 Upgrade 라는 값을 가진다.
Upgrade 와 마찬가지로 이 값이 없거나 다른 값이면 웹 소켓 접속을 중지시킨다.

Sec-WebSocket-Key
유효한 요청인지 확인하기 위해 사용하는 키 값

Sec-WebSocket-Protocol
사용하고자 하는 하나 이상의 웹 소켓 프로토콜 지정.

Sec-WebSocket-Version
클라이언트가 사용하고자 하는 웹소켓 프로토콜 버전.
현재 최신 버전 13

Origin
CORS 정책으로 만들어진 헤더.
Cross-Site Websocket Hijacking과 같은 공격을 피하기 위함.

 

👣 Opening Handshake 응답 헤더

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

HTTP/1.1 101 Switching Protocols
101은 HTTP에서 WS로 프로토콜 전환이 승인 되었다는 응답코드이다.

Sec-WebSocket-Accept
요청 헤더의 Sec-WebSocket-Key에 유니크 아이디를 더해서
SHA-1로 해싱한 후 base64로 인코딩한 결과이다.
웹 소켓 연결이 개시되었음을 알린다.

 

👣 Data transfer 

메시지
여러 프레임(frame)이 모여서 구성되는 하나의 논리적인 메시지 단위

프레임
통신에서 가장 작은 단위의 데이터.
패킷은 전 네트워크 통신 과정에서 가장 작은 단위의 데이터를 뜻하고,
프레임은 데이터 링크계층(이더넷)에서 주고 받는 가장 작은 단위를 의미한다.
작은 헤더 + payload 로 구성되어 있다.

 

👣 Closing Handshake

클라이언트 혹은 서버 양측 누구나 연결을 종료할 수 있다.
연결 종료를 원하는 측이 Close Frame 을 상대쪽으로 전송하면 된다.

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

WebSocket - SockJs  (0) 2023.10.05
CORS, SOP  (0) 2023.09.17
특별한 의미의 IP 주소  (0) 2023.08.04
웹 브라우저 저장소  (0) 2023.07.22
이더넷 프레임 구조  (0) 2023.07.21