나만의 작은 도서관
[TIL] 240621 캠프 68일차: 웹소켓과 http와의 관계, Socket.io의 기초 emit 이해 본문
[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
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: 서버가 클라이언트에게 "hello" 이벤트를 보냅니다.
- 코드 2: 클라이언트가 서버에게 "hello" 이벤트를 보냅니다.
- 이벤트 수신 주체:
- 코드 1: 클라이언트가 서버로부터 "hello" 이벤트를 수신합니다.
- 코드 2: 서버가 클라이언트로부터 "hello" 이벤트를 수신합니다.
- 메시지 흐름:
- 코드 1: 서버에서 클라이언트로 메시지가 흐릅니다.
- 코드 2: 클라이언트에서 서버로 메시지가 흐릅니다.
- 이벤트 처리 위치:
- 코드 1: 서버는 이벤트를 발송하고, 클라이언트는 이벤트를 수신하여 처리합니다.
- 코드 2: 클라이언트는 이벤트를 발송하고, 서버는 이벤트를 수신하여 처리합니다.
출처: https://socket.io/docs/v3/emitting-events/
오늘 한 일
- 타워 디펜스 팀 프로젝트 최종 제출 및 발표