나만의 작은 도서관

[TIL] 240621 캠프 68일차: 웹소켓과 http와의 관계, Socket.io의 기초 emit 이해 본문

Today I Learn

[TIL] 240621 캠프 68일차: 웹소켓과 http와의 관계, Socket.io의 기초 emit 이해

pledge24 2024. 6. 23. 22:12

오늘 배운 내용                                     

웹소켓과 http와의 관계

웹소켓과 http는 OSI 7계층 중 응용 계층(application layer)에 존재하는 통신 프로토콜들이다. 둘다 통신 프로토콜이라는 점에서 서로 관계없는 프로토콜이라고 알 수 있지만, 구별이 될 뿐 실제로는 전혀 관계가 없지는 않다. 

웹소켓은 TCP접속에 전이중 통신 채널을 제공한다는 점에서 http와 구별되지만, http에 업그레이드 헤더를 추가함으로써 http 프로토콜에서 웹소켓 프로토콜로 전환할 수 있을 정도로 http와의 호환이 되어있다. 아래 예시를 통해 http에서 웹소켓으로 연결을 업그레이드 하는 과정을 알아보자.

 

클라이언트 요청

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

 

위의 클라이언트 요청은 server.example.com이라는 호스트 주소에 웹소켓으로 연결하려는 클라이언트의 핸드쉐이크 요청이다. Updrade, Connection헤더에 위와 같이 적어줌으로써 웹소켓으로 업그레이드 해달라는 요청을 명시할 수 있다.

 

서버의 응답

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

클라이언트의 핸드쉐이크 요청이 정상적으로 처리되었다면, 서버는 위와 같은 응답을 보내게 된다. 서버의 응답 헤더 중, Upgrade, Connection헤더를 보게되면 정상적으로 웹소켓 프로토콜로 변경되었음을 알 수 있다. 

 

출처: https://ko.wikipedia.org/wiki/%EC%9B%B9%EC%86%8C%EC%BC%93

 

웹소켓 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 웹소켓(WebSocket)은 하나의 TCP 접속에 전이중 통신 채널을 제공하는 컴퓨터 통신 프로토콜이다. 웹소켓 프로토콜은 2011년 IETF에 의해 RFC 6455로 표준화되었으며 웹

ko.wikipedia.org

 

Socket.io의 기초 emit

Socket.io에서 emit은 기본적으로 아래와 같이 Node.js의 EventEmitter에서 따온 방식을 사용한다. 두 방식의 동작원리는 동일하다.

 

Socket.io emit

// server-side: io에서 연결을 감지하면, hello라는 이벤트를 "world"라는 argument를 넣어 발동한다.
io.on("connection", (socket) => {
  socket.emit("hello", "world");
});

// client-side: socket에서 hello라는 이벤트를 추가한다. 
// 이벤트가 감지되었을 때 실행할 코드는 입력받은 args를 출력하는 코드(console.log(arg))이다.
socket.on("hello", (arg) => {
  console.log(arg); // world
});

 

Node.js EventEmitter

import { EventEmitter } from 'node:events';

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter(); // myEmitter라는 이름의 EventEmitter 인스턴스를 생성. 
myEmitter.on('event', () => {	// 'event'라는 이벤트를 myEmitter에 추가
  console.log('an event occurred!');
});
myEmitter.emit('event'); // myEmitter에서 'event'라는 이벤트를 실행

 

위의 Socket.io emit을 또 다른 방식과 비교해보자.

 

두번째 Socket.io emit

// server-side
io.on("connection", (socket) => {
  socket.on("hello", (arg) => {
    console.log(arg); // world
  });
});

// client-side
socket.emit("hello", "world");

 

두 방식을 비교해보면 다음과 같은 차이점이 있다. 

 

코드의 차이점

  1. 이벤트 발송 주체:
    • 코드 1: 서버가 클라이언트에게 "hello" 이벤트를 보냅니다.
    • 코드 2: 클라이언트가 서버에게 "hello" 이벤트를 보냅니다.
  2. 이벤트 수신 주체:
    • 코드 1: 클라이언트가 서버로부터 "hello" 이벤트를 수신합니다.
    • 코드 2: 서버가 클라이언트로부터 "hello" 이벤트를 수신합니다.
  3. 메시지 흐름:
    • 코드 1: 서버에서 클라이언트로 메시지가 흐릅니다.
    • 코드 2: 클라이언트에서 서버로 메시지가 흐릅니다.
  4. 이벤트 처리 위치:
    • 코드 1: 서버는 이벤트를 발송하고, 클라이언트는 이벤트를 수신하여 처리합니다.
    • 코드 2: 클라이언트는 이벤트를 발송하고, 서버는 이벤트를 수신하여 처리합니다.

출처: https://socket.io/docs/v3/emitting-events/

오늘 한 일                                       

더보기
  • 타워 디펜스 팀 프로젝트 최종 제출 및 발표