본문 바로가기

IT 용어

웹소켓, 그리고 웹트랜스포트(feat. QUIC)

 

최근에 회사 동료가 채팅기능 관련해서 웹소켓 기능을 구현하느라 애좀먹었는데,

옛날에 한국회사에 있었을 때도 웹소켓에서 많이 들어봤었고, 비개발자들과 기술대화를 나눌때 종종 나와서,

개발자들이 비개발자들을 어떻게 해야 이해시킬지 몰라 애먹었던 용어이기도 함.

 

간단히 말하면 웹소켓이란 클라이언트와 서버간의 지속적 양방향 연결을 지속하는 프토로콜이다.

이기능을 쓰면 실시간 데이터 주고 받기가 된다.

 

한번 견결되면 서로 계속 자유롭게 데이터를 주고 받을 수 있다.

중요한 건 서버측에서 클라이언트로 데이터를 보낼 수 있다는 것.

스피드도 단순 HTTP 요청 으답보다 빠르다.

채팅, 실시간 알림 등에서 많이 씀.

 

이때 몇가지 개념들과 친숙해질 필요가 있는데,

HTTP/3, QUIC, 웹트랜스포트

 

QUIC은 전송 '프로토콜'. 구글에서 개발한 전송프로토콜. TCP대신 UDP를 사용해 빠름.

HTTP/3는 QUIC을 사용하는 'HTTP 프로토콜의 버전'. QUIC을 전송계층에서 사용해 웹페이지 로딩속도 개선

웹트랜스포트는 QUIC을 기반으로 한 '웹 통신 API'. QUIC기반 API. 스트리밍, 파일전송, 실시간 통신에서 유용.

 

즉, 근간이 QUIC이라 보면 된다.

 

흥미로운 건 웹트랜스포트는 웹소켓을 대체하는 개념으로도 볼 수 있는데. 지피티씨의 표 정리가 깔끔하니 참고

웹트랜스포트가 좀 더 진화된 고성능이지만, 현 시점에서 웹소켓과 보완적 관계로 보면 될 것 같다.

웹소켓이 텍스트와 바이너리 메시지 주고 받기에 특화됐다면,

웹트랜스포트는 스트리밍데이터와 파일전송에 특화됐다고 보면 될 듯.

 
특성
웹소켓 (WebSockets)
웹트랜스포트 (WebTransport)
기반 프로토콜
TCP 기반
QUIC 기반 (HTTP/3와 연관됨)
초기 연결
HTTP/1.1 또는 HTTP/2로 핸드셰이크 후 웹소켓 프로토콜로 업그레이드
HTTP/3를 사용하여 QUIC을 통해 연결
연결 유지
양방향 연결을 지속적으로 유지
양방향 연결을 지속적으로 유지, 다양한 스트리밍 및 파일 전송 지원
주요 사용 사례
채팅, 실시간 알림, 게임, 실시간 데이터 전송
고성능 실시간 데이터 전송, 스트리밍, 파일 전송 등
성능
TCP의 한계로 인해 상대적으로 높은 지연 시간
QUIC을 사용하여 낮은 지연 시간, 더 빠르고 안정적인 연결
기능성
실시간 양방향 통신에 중점
다양한 전송 방식 지원 (스트리밍, 파일 전송 등)
API 유연성
단순한 양방향 통신
더 고급 기능과 유연한 API 제공
호환성
대부분의 브라우저와 서버에서 지원
비교적 새로운 기술로 일부 환경에서 지원되지 않음
지원되는 표준
RFC 6455, HTTP/1.1 또는 HTTP/2
QUIC, HTTP/3, 웹표준으로 점진적으로 채택

 

리액트와 고 환경에서 웹소켓 구현예제

 

프론트엔드 React : ws엔드포인트로 날리고 받고

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

function App() {
  const [message, setMessage] = useState('');
  const [ws, setWs] = useState(null);

  useEffect(() => {
    const socket = new WebSocket('ws://localhost:8080/ws');

    socket.onopen = () => {
      console.log('WebSocket 연결 성공');
    };

    socket.onmessage = (event) => {
      console.log('서버에서 메시지 수신:', event.data);
      setMessage(event.data);
    };

    socket.onerror = (error) => {
      console.log('WebSocket 오류:', error);
    };

    socket.onclose = () => {
      console.log('WebSocket 연결 종료');
    };

    setWs(socket);

    return () => {
      socket.close();
    };
  }, []);

  const sendMessage = () => {
    if (ws) {
      ws.send('Hello from React');
    }
  };

  return (
    <div>
      <h1>WebSocket 예제</h1>
      <button onClick={sendMessage}>메시지 보내기</button>
      <p>서버로부터 받은 메시지: {message}</p>
    </div>
  );
}

export default App;
 

 

백엔드 Go : gorilla/websocket 패키지 사용, ws엔드포인트로 받고 주고

package main

import (
	"fmt"
	"log"
	"net/http"
	"github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

func handler(w http.ResponseWriter, r *http.Request) {
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Println(err)
		return
	}
	defer conn.Close()

	for {
		// 메시지 수신
		messageType, p, err := conn.ReadMessage()
		if err != nil {
			log.Println(err)
			break
		}

		// 수신한 메시지 출력
		fmt.Printf("Received: %s\n", p)

		// 메시지 전송
		if err := conn.WriteMessage(messageType, p); err != nil {
			log.Println(err)
			break
		}
	}
}

func main() {
	http.HandleFunc("/ws", handler)
	log.Fatal(http.ListenAndServe(":8080", nil))
}
 

 

 

 

 

'IT 용어' 카테고리의 다른 글

🚀 Rust + WebAssembly: 차세대 웹 개발?  (1) 2025.02.05