FE

🚀 웹소켓(WebSocket) - React에서 WebSocket 구현

이진지니지니진 2025. 2. 23. 23:46

새로운 프로젝트에 실시간 채팅 기능을 맡게 되어, 웹소켓(WebSocket)을 어떻게 구현할지 고민하게 되었다.

실시간 채팅이지만, 텍스트로만 이루어지는거라 간단하고 빠르게 구현할 수 있는 방법을 찾아보았다.

이에 React 환경에서 손쉽게 웹소켓을 관리할 수 있도록 도와주는 react-use-websocket 라이브러리를 선택!

 

왜 react-use-websocket을 사용했나

방식 라이브러리 자동재연결 JSON 지원 백엔드  
기본 WebSocket 직접 구현 new WebSocket() ❌ (직접 구현 필요) ❌ (문자열 전송) 기본 WebSocket 지원 서버 가장 가볍지만, 직접 상태 관리 & 재연결 구현 필요
react-use-websocket react-use-websocket 기본 WebSocket 지원 서버 자동 재연결 & JSON 지원, 사용이 간편
socket.io-client socket.io-client 백엔드가 Socket.IO 사용 이벤트 기반 메시지 처리 필요할 때
ws (Node.js 전용) ws 백엔드가 Node.js + ws Node.js 서버(WebSocket)와 직접 통신 시 사용
STOMP (Spring Boot + 메시징) @stomp/stompjs 백엔드가 STOMP 지원 (Spring Boot, RabbitMQ 등) Spring Boot 기반 Pub/Sub 메시징 시스템 구축 시 유용

 

react-use-websocket

https://www.npmjs.com/package/react-use-websocket

 

react-use-websocket

React Hook for WebSocket communication. Latest version: 4.13.0, last published: 19 days ago. Start using react-use-websocket in your project by running `npm i react-use-websocket`. There are 109 other projects in the npm registry using react-use-websocket.

www.npmjs.com

 

  • 간편한 Hook: useWebSocket Hook을 통해 간단하게 WebSocket 연결을 생성하고 관리할 수 있음
  • 자동 재연결: 연결이 끊어졌을 때 자동으로 재연결하는 기능을 내장하여, 안정적인 통신 환경을 제공
  • 상태 관리: 현재 연결 상태, 마지막 메시지, 에러 상태 등을 쉽게 확인할 수 있어 디버깅과 사용자 피드백에 유용

+ npm 다운로드 수와 최근 업데이트 내역을 보면 지속적으로 관리되고 있음을 확인할 수 있어 더욱 믿음이 갔다!

 

📑 DOCS: https://github.com/robtaussig/react-use-websocket

 

GitHub - robtaussig/react-use-websocket: React Hook for WebSocket communication

React Hook for WebSocket communication. Contribute to robtaussig/react-use-websocket development by creating an account on GitHub.

github.com

 

react-use-websocket 사용법

- 기본 예제

문서에 있는 기본 예제이다. 기본 예제만 봐도 사용법이 매우 쉽다!

import React, { useState, useCallback, useEffect } from 'react';
import useWebSocket, { ReadyState } from 'react-use-websocket';

export const WebSocketDemo = () => {
  // 연결할 WebSocket 서버 URL
  const [socketUrl, setSocketUrl] = useState('wss://echo.websocket.org');
  // 수신한 메시지
  const [messageHistory, setMessageHistory] =
    useState < MessageEvent < any > [] > [];

  // useWebSocket Hook을 통해 sendMessage, lastMessage, readyState를 제공받음
  const { sendMessage, lastMessage, readyState } = useWebSocket(socketUrl);

  useEffect(() => {
    if (lastMessage !== null) {
      setMessageHistory((prev) => prev.concat(lastMessage));
    }
  }, [lastMessage]);

  // 다른 WebSocket 서버로 URL 변경
  const handleClickChangeSocketUrl = useCallback(
    () => setSocketUrl('wss://demos.kaazing.com/echo'),
    []
  );

  const handleClickSendMessage = useCallback(() => sendMessage('Hello'), []);

  // 연결 상태
  const connectionStatus = {
    [ReadyState.CONNECTING]: 'Connecting',
    [ReadyState.OPEN]: 'Open',
    [ReadyState.CLOSING]: 'Closing',
    [ReadyState.CLOSED]: 'Closed',
    [ReadyState.UNINSTANTIATED]: 'Uninstantiated',
  }[readyState];

  return (
    <div>
      <button onClick={handleClickChangeSocketUrl}>
        Click Me to change Socket Url
      </button>
      <button
        onClick={handleClickSendMessage}
        disabled={readyState !== ReadyState.OPEN}
      >
        Click Me to send 'Hello'
      </button>
      <span>The WebSocket is currently {connectionStatus}</span>
      {lastMessage ? <span>Last message: {lastMessage.data}</span> : null}
      <ul>
        {messageHistory.map((message, idx) => (
          <span key={idx}>{message ? message.data : null}</span>
        ))}
      </ul>
    </div>
  );
};

 

 

[useWebSocket Hook]

  • sendMessage: 메시지 전송 함수
  • lastMessage: 최근에 수신한 메시지
  • readyState: 연결 상태

[readyState]

readyState 값은 기본 WebSocket API에서 사용하는 숫자와 동일한 의미이다.

+ UNINSTANTIATED(일반적으로 -1)

https://developer.mozilla.org/ko/docs/Web/API/WebSocket/readyState

 

이외에 설명이 문서에 매~~~우 잘 되어있기 때문에 보면서 간단하게 웹소켓을 구현할 수 있다!

 

// 실제 사용한 코드 일부 예제
// onOpen, onClose 메소드를 통해 연결된 상태, 연결 종료된 상태에 따라 작업을 할 수 있다.
const { sendMessage, lastMessage, readyState } = useWebSocket(wsUrl, {
    onOpen: () => console.log('✅ WebSocket 연결됨!'),
    onClose: (event) => console.log(`❌ WebSocket 연결 종료됨! 코드: ${event.code}`),
    shouldReconnect: () => true,
});

'FE' 카테고리의 다른 글

Web Worker  (1) 2025.04.29
🍪 쿠키(Cookie)  (0) 2025.01.07