Web

[Web]웹 소켓(Web Socket) 이란?

죵욜이 2025. 1. 6. 23:09

웹소켓이란?

  • 웹소켓은 클라이언트와 서버 간의 양방향, 실시간 통신을 가능하게 하는 프로토콜이다

많은 사람들이 토이프로젝트를 진행할때 채팅기능을 구현하려고 하며

이때 주로 고려하는기술로 웹소켓과 레디스를 꼽는다.

 

그렇다면 여러가지 후보군들 가운데 왜 웹소켓이어야 하며

이러한 프로토콜이 왜 만들어졌는지 이해해보자.


웹소켓의 등장 배경

초기의 인터넷 통신 방식은 HTTP프로토콜을 이용한 클라이언트(요청) -> 서버(응답) 모델을 통해 진행되었다.

 

하지만 이러한 방식은 클라이언트가 요청을 보내야만 서버가 응답을 할 수 있어서 

실시간으로 데이터를 주고받는 것에 한계가 있었다.

 

그래서 실시간성이 필요한 작업을 할때에는 

클라이언트가 새로운 데이터가 있는지 서버에게 짧은시간 간격을 두고 지속적인 요청을 보낼 수 밖에 없었다.

 

그 결과 불필요한 트래픽이 발생하게되고 서버의 비용증가로 이루어졌다.

또한 요청과 응답사이의 지연시간이 있어서 통신의 효율성이 대폭 하락하였다.


웹소켓 이전의 통신 방식

위에서 말한 이유들때문에 실시간통신의 필요성을 느끼게되었으며 바로 웹소켓이 탄생한것이 아닌 여러가지 기술들을 거치고나서야 만들어졌다.

이전에 주로사용되던 기술들은 무엇이 있는지 알아보자


폴링(Poling)

폴링이란?

클라이언트가 주기적으로 서버에 요청을 보내는 방식

즉, 일정 시간을 정해 놓고 새로운 데이터가 있는지 요청을 보내서 확인한다.

 

이러한 과정엔 당연히 불필요한 요청의 수가 많아지며 서버비용이 증가하며 위에서말한 단점이 명확하게 드러나게된다.

 

이러한 문제점을 개선해보고자 그다음 나온것이 롱폴링 기법이다.


롱 폴링 (Long Polling)

 

롱폴링이란?

폴링과 동일하게 클라이언트가 서버에 요청을 보내면

서버는 새로운 데이터가 없다면 일정 시간 동안 응답을 하지 않고 새로운 데이터가 있을 떄까지 기다린다.

 

새로운데이터가 생기면 그에대한 응답을 보내고

정해둔 일정시간 동안 새로운 데이터가 안생긴다면 Time Out 이 발생하며, 이때 Time Out 을 응답한다.

 

이러한 방식 역시 폴링에 비해 개선되었지만 여전히 불필요한 요청이 발생하며, 요청과 응답사이의 지연시간도 불가피하다.


SSE (Server-Sent-Event)

SSE 라고 불리는 방식은 폴링과는 다르게 실시간 통신은 가능하다.

 

클라이언트가 최초로 한번 서버에 연결을 요청하면

서버는 요청을 받고, 새로운 데이터가 생길때마다 적절한 처리를 한후 클라이언트에게 응답을 반환한다.

 

간단히 말하면 최초로 연결된 HTTP통신을 종료하지않고 유지하는 방식이다.

 

하지만 이러한방식은 최초연결이후 서버만 일방적으로 응답할수 있고, 프론트는 요청을 보낼수가 없다.

즉 듣기만 할수있는 라디오와 같다고 볼 수 있다.

 

그래서 실시간통신은 가능하지만 단방향이라는 한계점이 있으며

이러한 단방향실시간통신이 유효한 알림같은 기능을 구현할때 주로 사용되는 기법이다.

 

하지만 우리가원하는것은 채팅기능을 구현하기위한 실시간 양방향 통신이다.

이러한 문제점을 해결하기위해 등장한것이 바로 웹소켓 이다.


웹 소켓 (Web Socket)

웹소켓 은 HTML5 에 등장한 실시간 웹 애플리케이션을 위해 설계된 통신 프로토콜이며

TCP(Transmission Control Protocol)기반이다.

 

TCP 기반으로 한 웹소켓은 신뢰성있는 데이터 전송을 보장하고, 메시지 경계를 존중하고, 순서가 보장된 양방향 통신을 제공할 수 있다.

 

일반적인 HTTP프로토콜과 달리, 클라이언트와 서버간의 최초연결이 이루어지면

이 연결을 통해 양방향 통신을 지속적으로 할 수 있다.

 

 

이때, 데이터는 패킷(packet) 형태로 전달되며, 전송은 연결중단이나 추가 HTTP요청 없이 양방향으로 이루어진다.

- 패킷 : 네트워크 통신에서 데이터를 작은 조각으로 나눠서 전송하는 단위를 말한다.

 

 

연결

웹소켓을 연결하려면 ws 라는 특수 프로토콜을 사용한다

ex) ws://localhost:8000:api/socket/chat/

- ws 말고 wss:// 도 있으며 HTTP 와 HTTPS 관계와 유사하다고 이해하면 된다.

소켓이 정상적으로 생성되면 아래 4개의 이벤트를 사용할 수있다.

  • open : 연결이 성공적으로 되었을 때 발생
  • message : 데이터를 수신하였을 때 발생
  • error : 연결 상 에러가 생겼을 때 발생
  • close : 연결이 종료되었을 때 발생

 

웹소켓 핸드셰이크 (handshake)

핸드셰이크는 클라이언트와 서버가 웹소켓 연결을 맺기 위한 과정중 하나이다

웹소켓은 처음부터 웹소켓 프로토콜을 사용하지 않고, 기존 HTTP 요청을 이용해서 연결을 시작한 후, 

웹소켓으로 업그레이드 하는 방식으로 동작한다.

 

 

클라이언트가 HTTP 요청을 보내면

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

 

  • Upgrade: websocket → 웹소켓 연결로 변경하겠다는 뜻
  • Connection: Upgrade → 연결을 업그레이드하겠다는 뜻
  • Sec-WebSocket-Key → 서버가 응답할 때 검증하는 키
  • Sec-WebSocket-Version → 웹소켓 프로토콜 버전

서버는 101 Switching Protocols 응답을 보낸다 (웹소켓 연결 승인)

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

 

 

  • 101 Switching Protocols → HTTP에서 웹소켓으로 프로토콜 변경
  • Sec-WebSocket-Accept → 클라이언트의 Sec-WebSocket-Key를 기반으로 생성한 값 (웹소켓 연결 검증)

 

핸드셰이크가 성공하면 클라이언트와 서버는 웹소켓 프레임을 이용해 실시간 데이터 송수신 가능하며 웹소켓 연결이 완료된것이다.


웹소켓의 기본개념을 알았고

내가진행중인 장고프로젝트에 적용을 해야한다.

 

그렇다면 장고에서 웹소켓을 어떻게 쓰냐?

라고하면 매우 어렵다.

ASGI서버를 직접 설정하고, 웹소켓 연결 및 메시지 처리 로직을 직접 구현해야한다

ex) 웹소켓을 직접 처리하는 파이썬코드와 ASGI서버를 설정해서 요청을 처리해야함

 

하지만 장고에는 웹소켓을 편하게 설정하고 관리할 수 있게 도와주는 Django Channels 라는 라이브러리가 있다.

 

Django Channels 는 장고 애플리케이션에 웹소켓, HTTP2, 비동기작업 처리 등을 추가할 수 있게 해주는 라이브러리로

장고가 기본적으로 지원하는게 아닌 '비동기'프로토콜을 처리할 수 있게 만들어준다.

 

그래서 이제 프로젝트 진행을 위해 웹소켓을 편하기 쓰기위해 장고채널스에 대해 학습해보려고 한다.

 

 

웹 소켓 공식문서 : https://developer.mozilla.org/ko/docs/Web/API/WebSocket

 

WebSocket - Web API | MDN

WebSocket 객체는 WebSocket 서버 연결의 생성과 관리 및 연결을 통한 데이터 송수신 API를 제공합니다.

developer.mozilla.org