Skip to main content

Command Palette

Search for a command to run...

웹소켓에 대해 알아보자

웹소켓의 장단점, 사용법, 주의사항 등을 정리했습니다

Published
3 min readView as Markdown
웹소켓에 대해 알아보자
T

Software engineer for web tech. Interested in sustainable growth as software engineer.

웹소켓(WebSocket)은 클라이언트와 서버 간에 실시간, 양방향, 지속적인 데이터 통신을 가능하게 하는 기술입니다. HTTP 프로토콜과 달리, 웹소켓은 한 번 연결이 맺어지면 그 연결을 유지하면서 데이터를 빠르게 주고 받을 수 있습니다.

장점 and 단점

장점

  1. 양방향 통신: 클라이언트와 서버의 연결이 유지되는 동안 언제든 서로에게 데이터를 주고 받을 수 있습니다.

  2. 낮은 지연 시간: 연결이 되어있는 상태이기 때문에 데이터 교환 시 서로를 검증하는 시간이 없어서 HTTP 요청보다 지연 시간이 낮습니다.

  3. 효율적인 자원 사용: 한번의 연결 설정만으로 데이터를 주고 받을 수 있기 때문에 HTTP와 다르게 연결을 설정할 때 마다 사용되는 컴퓨팅 자원들을 아낄 수 있습니다.

단점

  1. 호환성 문제: 구형 브라우저나 일부 환경에서는 웹소켓을 지원하지 않을 수 있습니다.

  2. 스케일링 이슈: 많은 수의 연결을 관리해야 하는 경우, 서버의 부하 및 아키텍처 설계가 복잡해질 수 있습니다.

    • 예를 들어 실시간 채팅 어플리케이션을 구현할 경우 자동 재연결을 보장하거나, 메세지 순서를 보장하거나, 누락된 메세지를 재전송하도록 처리해야하는 등 고려해야 할 사항들이 많아집니다.

리액트에서 웹소켓의 기본 사용법

  • 보통 useEffect 훅 내에서 웹소켓 연결을 설정하고, 연결을 종료하는 로직을 작성합니다.

  •   import React, { useEffect } from 'react';
    
      function ChatComponent() {
          useEffect(() => {
              const ws = new WebSocket('wss://sample.com/chat');
              ws.onopen = () => {
                  console.log('Connected');
              }
              ws.onmessage = (event) => {
                  console.log('Message from sever ', event.data);
              }
    
              // 언마운트 시 연결 종료 처리
              return () => {
                  ws.close();
              }
          }, []); // 마운트 시 1회만 실행
    
          return <div> Chat </div>;
      }
    

리액트에서 웹소켓 사용 시 주의사항

  1. 재연결 로직: 네트워크 불안정, 모바일 브라우저의 사용성 등으로 인해 연결이 끊길 수 있습니다. 이를 위해 자동 재연결 로직을 구현하는 것이 좋습니다.

  2. 메모리 누수 방지: 웹소켓 이벤트 리스너 등록시에는 컴포넌트 언마운트 시 이를 제거해야 메모리 누수를 방지할 수 있습니다.

  3. 보안 프로토콜 사용: wss:// 프로토콜을 사용하여 데이터 전송 시 암호화 되도록 처리해주는 편이 좋습니다.

주의사항을 반영한 예시

import React, { useEffect, useRef } from 'react';

function ImprovedChatComponent() {
    const wsRef = useRef(null);

    useEffect(() => {
        const setWebSocket = () => {
            const ws = new WebSocket('wss://sample.com/chat');
            ws.onopen = () => {
                console.log('Connected');
            };
            ws.onclose = () => {
                console.log('Disconnected. Attempting to reconnect...');
                setTimeout(setWebSocket, 3000); // 연결 끊기면 3초뒤 재시도
            };

            // useRef를 사용하여 웹소켓 인스턴스 저장
            wsRef.current = ws;
        }

        setWebSocket();

        // 언마운트 시 웹소켓 연결 종료
        return () => {
            if (wsRef.current) {
                wsRef.current.close();
            }
        }
    }, []);

    return <div> Chat </div>;
}

onclose 이벤트 핸들러 내에서 연결이 끊어졌을 때 자동으로 재연결을 시도하는 로직을 구현했습니다.
useRef를 사용하여 웹소켓 인스턴스를 저장하고 있는데, 이렇게 함으로서 컴포넌트 생명주기에 맞춰 적절하게 웹소켓 연결과 종료를 할 수 있어서 자원 낭비를 막을 수 있습니다.

마치며

운영하는 서비스에서 웹소켓 관련 코드를 수정하다보니 웹소켓에 대해 잘 모르고 있다는 점을 반성하며 내용을 정리하는 글을 써봤습니다. 웹소켓의 가장 어려운 부분은 여러가지 연결에 대한 설계일 것이라고 판단되지만, 클라이언트 단에서도 리액트 컴포넌트의 생명주기에 맞춰서 세심하게 설정해줘야 한다는 점을 알 수 있었습니다.

More from this blog

프론트엔드는 경계를 다루는 직무가 되어간다

프론트엔드는 원래도 복잡했습니다. 브라우저마다 다른 렌더링, 상태 동기화, 성능, 접근성 — 화면 하나 제대로 만드는 데 신경 쓸 게 늘 많았습니다. 다만 그 복잡함은 대체로 한 방향을 향했습니다. 이 UI를 어떻게 만들까, 상태를 어떻게 관리할까, 클릭하면 무엇이 바뀌어야 할까. 그런데 요즘 질문의 축이 하나 더 늘고 있습니다. 이 UI는 서버에서 먼저

Jul 20, 20266 min read

AI가 코드를 짜는 시대, 나는 리뷰를 못 따라가고 있었다

솔직히 말하면, 요즘 PR을 제때 리뷰하지 못하고 있습니다. 개발 속도는 빨라졌는데 리뷰 속도는 그대로입니다. 예전엔 하루 이틀이면 처리하던 게 이제는 며칠씩 밀립니다. 처음엔 제가 게을러진 탓인가 싶었습니다. 돌아보니 그게 아니었습니다. AI 도구를 쓰면서 코드가 쏟아지는 속도가 달라졌습니다. 한 사람이 만들어내는 코드 양이 예전과 비교가 안 됩니다. P

Mar 18, 20263 min read
AI가 코드를 짜는 시대, 나는 리뷰를 못 따라가고 있었다

테드풀의 한 입 지식

78 posts

가볍게 정리하는 기록들입니다.