Study/CS

WebSocket에 대해서 알아보기

다니니니 2024. 11. 11. 13:06
728x90

들어가며

이번 프로젝트에서 실시간 채팅을 구현하기 위해 웹소켓을 썼지만 정확히 어떤 것이고 어떤 원리로 동작하는지에 대해 잘 안다고 할 수 없다.

이왕 썼으니 원리에 대해서 잘 알아보려고 한다.

 

웹 소켓(Web Socket)이란?

웹 소켓은 양방향 통신을 위한 프로토콜(약속) 이다.

주로 웹 서버와 웹 브라우저가 실시간으로 메시지를 주고받을 때 사용한다. 

HTTP 통신은 클라이언트가 서버에 요청을 보내고, 서버가 응답하는 통신을 따른다.

보통 작업에는 문제가 없지만, 채팅과 같이 실시간으로 데이터를 주고받는 것에서는 트래픽을 불필요하게 증가시키고,

서버의 비용을 증가시키며 요청과 응답사이에 지연시간이 있어서 실시간 통신의 효율성을 저하시킬 수 있다.

 

이런 상황을 해결하기 위해 나온 것이 웹 소켓이다.

웹 소켓은 HTML5 부터 등장한 웹 표준 기술이다.(따라서 너무 오래된 브라우저에서는 작동하지 않을 수 있다.)

HTTP 와는 다르게 최초 연결이 이루어지면 지속적으로 연결이 유지되는 것이 특징이다.

매번 메시지 전송 시에 새로 연결을 맺을 필요가 없어 빠르고 효율적이다.

출처 : 코딩온 교안 자료

웹 소켓의 특징을 정리하면 다음과 같다.

  • 양방향 통신 : 클라이언트와 서버간에 실시간 양방향 통신 가능
  • 낮은 오버헤드 :  연결 후에는 연결이 계속 유지되므로 통신 오베헤드가 낮다.
  • 이벤트 기반 : 서버와 클라이언트 간의 데이터 전송은 이벤트 기반으로 이뤄진다.

웹 소켓의 작동 원리

1) 핸드셰이크로 초기 연결

클라이언트가 서버로 HTTP 요청을 한다.

웹소켓 연결을 요청하기 위해 HTTP 요청 헤더에 Upgrade : websocket 와 Connection : Upgrade 를 포함한다.

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

 

서버는 요청을 확인하고 연결을 승인하면 응답을 보낸다.

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

 

101 상태코드와 Switching Protocols 응답을 반환하며, 이후 웹소켓 연결이 성립된다.

이렇게 웹소켓 통신 전 클라이언트와 서버가 HTTP 로 메시지를 주고 받는 것을

핸드셰이크(handshake) 라고 한다.

이 핸드셰이크 과정이 끝나면 HTTP 연결은 웹소켓 연결로 전환되며, 양방향 통신이 시작된다.

출처 : 코딩온 교안 자료

2) 데이터 전송

웹소켓 프로토콜은 데이터를 송수신할 때, 메시지를 프레임 단위로 나누어 전송한다.

(프레임이란 클라이언트와 서버 간에 데이터를 작은 단위로 나누어 전송하는 방식이다.)

클라이언트는 메시지를 서버에 전송하고, 서버는 메시지를 처리하고 응답을 클라이언트로 전송한다.

데이터는 지속적인 연결 상태에서 실시간으로 주고 받는다.

 

메시지는 이벤트 기반으로 동작한다. 

 

 

3) 연결 종료

웹소켓 연결은 클라이언트나 서버 중 한쪽이 명시적으로 연결 종료를 요청하기 전까지 유지된다.

연결 종료 요청은 종료 프레임을 통해 이루어지며, 

한쪽에서 종료 요청을 보내면, 상대방은 종료를 확인하고 연결을 닫는다.

 

클라이언트에서 웹소켓을 연결하는 방법

클라이언트에서는 브라우저의 웹 소켓 객체를 사용해서 웹 소켓 연결을 생성하고 관리한다.

웹 소켓 객체는 new 키워드를 사용해 만들 수 있다.

// 웹소켓 서버 URL
const socket = new WebSocket('ws://www.test.com/chat')

// 연결 성공
socket.onopen = () => {
    console.log('WebSocket 연결 성공');
    socket.send('Hello~'); // 서버로 메시지 전송
};

// 메시지 수신
socket.onmessage = (event) => {
    console.log('서버로부터 받은 메시지:', event.data);
};

// 에러 처리
socket.onerror = (error) => {
    console.error('WebSocket 에러:', error);
};

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

 

이 방법 외에도 Socket.io 와 stomp.js 라이브러리를 통해서 더 쉽게 웹소켓을 구현할 수 있다.

 

1) Socket.io

Socket.io는 양방향 및 이벤트 기반 통신을 실시간으로 가능하게 하는 라이브러리다.

주로 Node.js 서버로 구축했을 때 자주 사용된다. 

Socket.io 의 기본 이벤트는 아래와 같다.

  • connection / connect : 클라이언트가 서버에 연결되었을 때 발생
  • disconnect : 클라이언트가 연결을 해제했을 때 발생
  • disconnecting : 클라이언트가 연결을 해제하려는 경우에 발생
  • error : 연결 중 오류가 발생했을 때

그리고 emit 메서드와 on 메서드가 이벤트를 지정할 수 있다.

emit 메서드는 이벤트를 보내는 쪽, on 메서드는 이벤트를 받는 쪽이다.

// 이벤트명을 지정하고 메시지를 보냄
socket.emit('전송할 이벤트명', msg)

// 해당 이벤트를 받고 콜백함수 실행
socket.on('받을 이벤트명', (msg) => {...})

 

이것을 이용한 서버 코드는 아래와 같다.

server.js

// server.js
const express = require('express');
const http = require('http');
const SocketIO = require('socket.io');

// Express와 HTTP 서버 설정
const app = express();
const server = http.createServer(app);

// Socket.IO 서버 설정
const io = socketIO(server);

// 정적 파일 제공 (HTML, CSS, JS)
app.use(express.static('public'));

// 클라이언트 연결 이벤트
io.on('connection', (socket) => {
  console.log('연결 완료', socket.id);

  // 메시지 수신
  socket.on('chat message', (msg) => {
    console.log('Message received:', msg);

    // 메시지를 모든 클라이언트에 브로드캐스트
    socket.emit('chat message', msg);
  });

  // 연결 해제
  socket.on('disconnect', () => {
    console.log('연결 종료', socket.id);
  });
});

// 서버 실행
const PORT = 3000;
server.listen(PORT, () => {
  console.log(`서버 실행 중 http://localhost:${PORT}`);
});

그럼 클라이언트 코드는 아래와 같이 할 수 있다.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Socket.IO Chat</title>
  <style>
    body { font-family: Arial, sans-serif; }
    #chat { max-width: 500px; margin: 0 auto; padding: 20px; }
    #messages { list-style: none; padding: 0; }
    #messages li { padding: 5px 10px; }
    #form { display: flex; gap: 10px; margin-top: 10px; }
    input { flex: 1; padding: 10px; }
    button { padding: 10px; cursor: pointer; }
  </style>
</head>
<body>
  <div id="chat">
    <h1>Socket.IO Chat</h1>
    <ul id="messages"></ul>
    <form id="form">
      <input id="input" autocomplete="off" placeholder="Type a message..." />
      <button>Send</button>
    </form>
  </div>
  <script src="/socket.io/socket.io.js"></script>
  <script>
    // Socket.IO 클라이언트 설정
    const socket = io();

    // DOM 요소 가져오기
    const form = document.getElementById('form');
    const input = document.getElementById('input');
    const messages = document.getElementById('messages');

    // 메시지 전송
    form.addEventListener('submit', (event) => {
      event.preventDefault();
      if (input.value) {
        socket.emit('chat message', input.value);
        input.value = '';
      }
    });

    // 메시지 수신
    socket.on('chat message', (msg) => {
      const li = document.createElement('li');
      li.textContent = msg;
      messages.appendChild(li);
      window.scrollTo(0, document.body.scrollHeight);
    });
  </script>
</body>
</html>

 

 

2) STOMP.js

STOMP는 Simple Text Oriented Messaging Protocol 의 약자로, 메시징 프로토콜을 지원하는 

SockJS 와 함께 사용한다. 

SockJS 는 웹소켓을 지원하지 않는 구형 브라우저나 환경에서도 실시간 양방향 통신을 가능하게 해주는

JavaScript 라이브러리다.

이번 프로젝트에서는 서버를 스프링 부트로 구축했기 때문에 STOMP.js 를 사용해서 실시간 채팅을 구현했다.

(참고 : [React] WebSocket으로 단체 채팅방 만들기)

 

 

 

Reference

코딩온 교안 자료

 

https://yozm.wishket.com/magazine/detail/1911/

 

웹소켓으로 개발하기 전 알아야 할 것들 | 요즘IT

웹소켓(Web Socket) 프로토콜은 HTTP와는 다른 통신 프로토콜로 웹 서버와 웹 브라우저가 서로 실시간 메시지를 교환하는 데에 사용된다. 최근 웹소켓을 활용해 소규모 메타버스 서비스를 개발하는

yozm.wishket.com

https://sendbird.com/ko/developer/tutorials/websocket-vs-http-communication-protocols

 

WebSocket 대 HTTP 통신 프로토콜: 개발자에게 있어 차이점은 무엇인가?

WebSocket 대 HTTP 통신 프로토콜의 강점, 약점 및 트레이드오프에 대한 소개.

sendbird.com

https://velog.io/@sj_yun/Web-Socket%EC%9D%B4%EB%9E%80

 

웹 소켓 (Web Socket)이란?

이번에 실무를 경험하게 되면서 처음으로 웹소켓을 사용하게 되었습니다. 실시간으로 CCTV 영상을 화면에 구현하기 위해 웹소켓을 사용하였습니다.웹 소켓의 역할만 두루뭉실하게 알고 있었던

velog.io

https://www.daleseo.com/websocket/

 

실시간 양방향 통신을 위한 웹소켓(WebSocket)

Engineering Blog by Dale Seo

www.daleseo.com

https://velog.io/@jinyeong-afk/%EA%B8%B0%EC%88%A0-%EB%A9%B4%EC%A0%91-%EC%9B%B9%EC%86%8C%EC%BC%93-%EA%B0%9C%EB%85%90-%EB%B0%8F-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC

 

[기술 면접] 웹소켓 개념 및 동작 원리

웹소켓은 웹 브라우저와 웹 서버 간의 양방향 통신을 지원하는 프로토콜이다. 이것은 HTTP 프로토콜의 단점 중 하나인 클라이언트에서 서버로 요청을 보내고 서버는 그에 대한 응답을 보내는 단

velog.io

https://webcodur.tistory.com/71

 

[IT기술] 웹소켓의 기본적인 이해와 활용방법

목차 웹소켓 기술은 웹에서 실시간 양방향 통신을 가능하게 하여 사용자 경험을 크게 향상시킨다. 본 글에서는 이런 웹소켓의 필요성과 중요성을 탐구하고, 기술의 기본 개념부터 실제 응용까

webcodur.tistory.com

https://medium.com/@delivalue100/%EC%9B%B9%EC%86%8C%EC%BC%93-feat-tcp-%EC%86%8C%EC%BC%93-http-b35171b5f4f0

 

웹소켓 feat. TCP, 소켓, HTTP

들어가기 앞서

medium.com

 

728x90

'Study > CS' 카테고리의 다른 글

SSR 과 CSR 의 차이  (0) 2024.11.27
브라우저의 렌더링 과정  (0) 2024.11.25
TCP/UDP 알아보기  (1) 2024.11.12