카테고리 없음

웹소켓소켓

연 동 2025. 4. 23. 06:05

그간 웹소켓을 써보고싶었는데 드디어 회사에서 사용하게 되었습니다.

관련해서 공부해본 내용 정리를 해보려구요.

 

# 목차

1. 웹소켓이란?

2. WebSocket 동작 원리

3. WebSocket 라이브러리별 작동 방법

 

 

 

 

# 웹소켓(WebSocket)이란?

실시간 양방향 통신 프로토콜

기존 HTTP 통신은 클라이언트에서 요청을 보내야 서버에서 응답을 받을 수 있는 구조였습니다.

반면 웹소켓은 한번 연결이 성립되면 서버와 클라이언트가 서로 자유롭게 데이터를 주고받을 수 있는 양방향 통신이 가능합니다.

실시간 통신을 흉내내기 위해 과거에는 클라이언트가 일정 간격마다 서버에 요청을 보내는 '폴링(Polling)' 등의 기법이 사용되곤 했습니다.

하지만 폴링은 유의미한 데이터가 없더라도 계속해서 요청을 보내기 때문에, 불필요한 네트워크와 서버 자원을 소모하게 된다는 단점이 있었습니다. 

때문에 이를 실시간 양방향 통신으로 개선한 기술이 바로 WebSocket입니다.

 

웹소켓을 통해 비로소 선톡이 와야 답장하던 수동적인 서버에서 선톡도 보내는 능동적인 서버로 바꿔줄 수 있게 되었습니다.

 

 

# WebSocket 동작 원리

웹소켓은 기본적으로 4단계 과정을 통해 작동합니다.

 

1. HTTP Handshake

클라이언트는 웹소켓 요청을 하기 위해 헤더에 Upgrade: websocket를 포함하여 HTTP 요청을 합니다.

const socket = new WebSocket("ws://localhost:8081");

 

GET / HTTP/1.1
Host: localhost:8081
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: xxxxxxx
Sec-WebSocket-Version: 13

 

`Sec-WebSocket-Key`는 클라이언트가 보내는 임의의 문자열이며, 서버는 여기에 고정된 GUID를 붙여 SHA-1 해시 후 Base64 인코딩한 값을 `Sec-WebSocket-Accept`로 응답하여 핸드셰이크를 검증합니다.

 

 

2. 프로토콜 업그레이드

서버는 이 요청을 확인하고, 응답으로 101 Switching Protocols를 반환합니다.

이후 통신은 HTTP가 아닌 WebSocket 프로토콜로 전환됩니다.

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: yyyyyyy

 

 

3. 양방향 데이터 송수신(Full-Duplex)

연결이 유지되며 클라이언트와 서버는 텍스트나 바이너리 데이터를 실시간 송수신할 수 있습니다.

 

 

4. 연결 종료

어느 한 쪽이 close 프레임을 전송하면, 다른 쪽이 수락 후 연결을 종료합니다.

종료 시 1000(정상 종료), 1006(비정상 종료) 등의 상태 코드도 함께 전송됩니다.

socket.close();

 

 

 

 

WebSocket 라이브러리 별 작동 방법

## 기본 WebSocket API

브라우저에는 내장된 WebSocket API가 있어서 별도의 설치 없이 바로 사용할 수 있습니다.

 

 

- 백엔드에서 특정 포트로 웹소켓을 엽니다.

백엔드에서는 기본 내장 WebSocket API가 없기 때문에 'ws' 라이브러리를 설치해줘야 합니다.

const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8081 });

 

이렇게 WebSocket 서버를 별도의 포트에서 실행할 수도 있고,

HTTP 서버와 같은 포트를 사용하면서 특정 경로(예: /ws)에 WebSocket 엔드포인트를 설정할 수도 있습니다.

 

- 프론트엔드에서 약속된 포트로 웹소켓을 보냅니다.

const socket = new WebSocket("ws://localhost:8081")

ws:// 대신 wss://를 사용하면 SSL/TLS 보안이 가능합니다.

 

 

## Socket.IO 라이브러리

자동 재연결, 연결 복구 등 다양한 기능을 제공하는 실시간 통신 라이브러리입니다.

이 기능을 모두 사용하려면 프론트와 백엔드 모두에서 socket.io를 설치해줘야 합니다.

 

npm install socket.io-client

 

를 통해 설치를 해야 사용 가능합니다.

 

또한 리액트 코드에선 이렇게 Import해줘야 사용 가능합니다.

import { io } from "socket.io-client";
const socket = io('http://localhost:3000');

 

 

Socket.io는 프론트엔드 측에서

socket.on(eventName, callback)

socket.emit(eventName, Data)

을 통해 이벤트 처리를 하고 있습니다.

 

### socket.on(eventName, callback)

이 메서드를 통해 어느 한 쪽에서 특정 이벤트가 발생했을 때 실행할 코드를 등록합니다.

 

자주 사용하는 프론트엔드 측 socket 이벤트에는

- 'disconnect' : 연결이 끊겼을 때 발생

- 'message' : 기본 문자열 이벤트, 웬만하면 새로운 이벤트 사용하는게 좋습니다.

- 'error' : 오류 발생 시

- 'reconnect' : 자동 재연결 시도할 때 발생

이정도가 있겠네요. 위의 eventName에는 Socket.io가 기본으로 제공하는 내장 이벤트 이름입니다.

이외에도 서버와 함께 'chat:send', 'chat:typing' 등과 같은 커스텀 이벤트도 만들어줄 수 있습니다.

 

 

 

예를 들자면

// 프론트: 알림 수신 대기
socket.on('notification', data => {
  console.log('새 알림:', data.content);
});


// 백엔드: 알림 전송
socket.emit('notification', { type: 'new_comment', content: '새 댓글이 달렸어요!' });

 

이렇게 사용할 수 있겠네요.

 

 

 

### socket.emit(eventName, Data)

 

이 메서드를 통해 상대측에 이벤트와 데이터를 전송할 수 있습니다.

 

여기서도 위와 같은 기본 eventName을 사용할 수 있으며, 클라이언트와 백엔드가 같은 eventName을 지정하면 커스텀 이벤트로 사용 가능합니다.

 

// 프론트엔드
socket.emit('chat:send', {
  roomId: 'abc123',
  message: '안녕하세요!',
  sender: 'hojun',
});


// 백엔드 (서버)
socket.on('chat:send', (data) => {
  console.log('클라이언트로부터 받은 메시지:', data);
});

 

 

 

 


오늘은 WebSocket에 대해 알아봤습니다.

다음엔 더 좋은 글로 찾아뵐게요,

안녕!

728x90