welcome to sisi's space! ‎ε(*⌒▽⌒)੭*゚¨゚゚・*:..☆

Dev & Study

멋사 세미나 과제 3

Sisi_ 2024. 11. 7. 23:27

오늘은 멋사 세미나 과제를 수행하기 위해 다음의 세 가지 키워드로 글을 써보고자 한다.
- HTTP 프로토콜과 WebSocket 프로토콜의 특징 및 차이점
- Django ‘Channels’ 라이브러리 구조
- React ‘useWebSocket’ Hook 사용법

HTTP 프로토콜과 WebSocket 프로토콜의 특징 및 차이점

HTTP와 WebSocket은 공통적으로 웹 애플리케이션에서 정보를 주고받기 위해 사용되는 통신 프로토콜이지만, 그 방식과 목적에 약간의 차이가 있다.

HTTP와 WebSocket의 기본 개념

HTTP는 웹 개발자라면 누구나 익숙할 프로토콜이다. 클라이언트가 서버에 요청을 보내고 서버가 응답을 돌려주는 방식이다. 주로 페이지를 새로고침할 때마다 정보가 갱신된다. 이런 요청-응답 방식을 통해 데이터를 주고받는데, 상태가 없는(stateless) 방식이기 때문에 요청마다 새롭게 연결을 맺고 끊게 된다. 따라서 실시간으로 변화하는 데이터를 제공하는 데는 한계가 있다.
반면, WebSocket은 양방향 통신이 가능하도록 설계된 프로토콜이다. 연결이 성립되면 클라이언트와 서버가 실시간으로 데이터를 주고받을 수 있다. 연결이 끊어지기 전까지는 지속적인 통신이 가능하다는 점에서 HTTP와 차별화된다. 예를 들어 채팅 앱이나 주식 시세, 스포츠 경기 실시간 알림 같은 기능에서는 WebSocket을 사용하는 것이 훨씬 효율적이다.
WebSocket을 사용하면 지속적인 연결을 통해 데이터를 교환할 때 발생하는 오버헤드가 줄어드므로 효율성을 높일 수 있다. 또한 서버에서 클라이언트로 직접 데이터를 푸시할 수 있게 된다. 클라이언트가 지속적으로 서버에 폴링을 하지 않아도 되므로, 리소스 사용을 최소화하고 반응성을 향상시킨다. 여기에서 풀링이란, 하나의 장치(또는 프로그램)가 충돌 회피 또는 동기화 처리 등을 목적으로 다른 장치(또는 프로그램)의 상태를 주기적으로 검사하여 일정한 조건을 만족할 때 송수신 등의 자료처리를 하는 방식을 말한다. 그 이외에도 WebSocket에는 낮은 지연 시간, 유연성(포트 80 및 443을 통해 통신하므로, 대부분의 방화벽 및 프록시 서버에서 차단되지 않음)등의 특징이 있다.

Django ‘Channels’ 라이브러리 구조

기본적으로 Django는 HTTP를 사용하여 요청과 응답을 처리한다. 하지만 WebSocket과 같은 실시간 통신을 위해 Django에서는 Django Channels라는 라이브러리를 제공한다. 라이브러리 Channels는 Django 애플리케이션에 WebSocket 기능을 추가할 수 있게 해주고, 비동기 처리를 통해 실시간으로 데이터를 주고받을 수 있는 구조를 지원한다.

Django Channels의 구조를 간단히 살펴보면, 소비자(consumer)라는 개념이 존재한다. 소비자는 WebSocket 연결을 관리하고 메시지를 주고받을 수 있는 단위로 생각할 수 있다. 예를 들어, 채팅 애플리케이션의 메시지 수신과 발신을 담당하는 기능을 각각의 소비자로 구현할 수 있다. Channels는 또한 라우팅(routing)을 통해 특정 URL에 대해 WebSocket 연결을 특정 소비자와 연결시켜주는 역할을 수행한다.
Django Channels는 애플리케이션이 WebSocket을 필요로 할 때 유용하게 사용할 수 있는 라이브러리이지만,  이때에도 비동기적 작업 관리와 기타 설정이 필요하기 때문에 중급 이상의 Django 지식이 필요할 수 있을 것 같다.

React ‘useWebSocket’ Hook 사용법

이제 React를 사용하여 프론트에서 WebSocket을 어떻게 활용할 수 있는지 알아보자. 최근 useWebSocket이라는 Hook이 주목받고 있다고 하는데, 이 Hook은 클라이언트 측에서 WebSocket을 쉽게 사용할 수 있도록 해 준다. 특히, React 프로젝트에서 WebSocket을 활용하여 실시간 데이터를 받는 경우, useWebSocket을 사용하면 초기화나 연결, 연결 종료 등의 관리를 손쉽게 할 수 있다.

import { useState } from 'react';
import useWebSocket from 'react-use-websocket';

function MyComponent() {
  const [messageHistory, setMessageHistory] = useState([]);

  const { sendMessage, lastMessage } = useWebSocket('ws://example.com', {
    onMessage: (message) => {
      setMessageHistory((prev) => [...prev, message]);
    },
  });

  return (
    <div>
      <button onClick={() => sendMessage('Hello WebSocket!')}>
        Send Message
      </button>
      <ul>
        {messageHistory.map((message, idx) => (
          <li key={idx}>{message.data}</li>
        ))}
      </ul>
    </div>
  );
}

 

위 코드는 useWebSocket Hook을 사용하여 WebSocket 서버에 연결한 후, 메시지를 전송하고 받는 기능을 구현한 것이다. sendMessage 함수를 통해 메시지를 전송할 수 있고, lastMessage를 통해 서버로부터 받은 메시지를 관리할 수 있다.
useWebSocket hook을 사용하면 WebSocket 연결과 관련된 이벤트를 관리하는 로직을 훨씬 간편하게 구현할 수 있어서, 초보자 입장에서도 더 쉽게 WebSocket 기반 실시간 애플리케이션을 개발할 수 있을 것 같다.

참고한 글
https://velog.io/@moonshadow/WebSocket
https://velog.io/@sorin44/React-React에서-WebSocket을-사용하는-방법