Socket.IO ๋ž€?

Node.js ๊ธฐ๋ฐ˜์œผ๋กœ ๋ธŒ๋ผ์šฐ์ €์™€ ์„œ๋ฒ„ ๊ฐ„์˜ ์‹ค์‹œ๊ฐ„ ์–‘๋ฐฉํ–ฅ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ํ†ต์‹ ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค. WebSocket์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๋ธŒ๋ผ์šฐ์ €๋„ ์ง€์›ํ•˜๋ฉฐ ๋ฉ€ํ‹ฐ ๋””๋ฐ”์ด์Šค(web, android, ios, windows)๋ฅผ ์ง€์›ํ•˜๋Š” ํŠน์ง•์ด ์žˆ๋‹ค. ์ฆ‰, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ WebSocket์„ ์ง€์›ํ•˜๋ฉด ์ผ๋ฐ˜ WebScoket ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•˜๊ณ  ๊ฐ„๋‹จํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋ฉฐ, ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๋ธŒ๋ผ์šฐ์ €๋ฉด HTTP ๋กฑ ํด๋ง ๋ฐฉ์‹์œผ๋กœ ๋Œ€์ฒดํ•œ๋‹ค.

image

๋กฑ ํด๋ง(Long polling)

์ฃผ๊ธฐ์ ์œผ๋กœ ๋ฌดํ•œํžˆ ๋ฌผ์–ด๋ณด๋Š” polling ๋ฐฉ์‹๊ณผ๋Š” ๋‹ฌ๋ฆฌ long polling์€ Request๋ฅผ ๋ณด๋‚ด๊ณ  Time out ๋  ๋•Œ๊นŒ์ง€ ๋ฌดํ•œ์ • ๊ธฐ๋‹ค๋ฆฐ๋‹ค. Time out์ด ๋˜์–ด ์„œ๋ฒ„๊ฐ€ ๋Š์„ ๋•Œ Client๋Š” ์žฌ์—ฐ๊ฒฐํ•œ๋‹ค. ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ณ€๊ฒฝ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ์–ด Response๊ฐ€ ์˜จ๋‹ค๋ฉด ๋ฐ”๋กœ client์—๊ฒŒ ์ „๋‹ฌํ•˜๊ณ  ์—ฐ๊ฒฐ์ด ์ข…๋ฃŒ๋œ๋‹ค. Client๋Š” ์ •๋ณด๋ฅผ ๋ฐ›๋Š” ์ฆ‰์‹œ ๋‹ค์‹œ Request๋ฅผ ๋ณด๋‚ด๋Š” ์‹์œผ๋กœ ํ•˜์—ฌ ์—ฐ๊ฒฐ์€ ๋ฌดํ•œํžˆ ์ง€์†๋˜๋ฉฐ Client๋Š” ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค.

๋‹ค๋งŒ ๋‹ค์ˆ˜์˜ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋™์‹œ์— ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒ๋˜๋Š” ๊ฒฝ์šฐ ์„œ๋ฒ„์˜ ๋ถ€๋‹ด์ด ๊ธ‰์ฆํ•˜์—ฌ ๋‹ค์ˆ˜์˜ ์‚ฌ์šฉ์ž๊ฐ€ ๋™์‹œ์— ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š๋‹ค. ๋˜ํ•œ ์š”์ฒญ ๊ฐ„๊ฒฉ์ด ์ค„์–ด๋“œ๋ฉด polling ๋ฐฉ์‹๋ณด๋‹ค ๋” ๋งŽ์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด๊ฒŒ ๋œ๋‹ค. image

WebSocket

์›น ๋ธŒ๋ผ์šฐ์ €๋Š” http ํ”„๋กœํ† ์ฝœ์„ ๊ธฐ๋ฐ˜์œผ๋กœ Request/Response๋กœ ๋™์ž‘ํ•˜๋Š”๋ฐ ์‹ค์‹œ๊ฐ„ ํ†ต์‹ ์€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. Websocket์€ ์›น ์„œ๋ฒ„์™€ ์›น ๋ธŒ๋ผ์šฐ์ € ๊ฐ„ ์‹ค์‹œ๊ฐ„ ์–‘๋ฐฉํ–ฅ ํ†ต์‹  ํ™˜๊ฒฝ์„ ์ œ๊ณตํ•ด์ฃผ๋Š” ์‹ค์‹œ๊ฐ„ ํ†ต์‹  ๊ธฐ์ˆ ์ด๋‹ค. WebSocket์€ ์›น ๋ธŒ๋ผ์šฐ์ €๋งŒ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— Socket.io ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›น ๋ธŒ๋ผ์šฐ์ € ์ง€์› ์—ฌ๋ถ€์— ๋”ฐ๋ผ webSocket์„ ์‚ฌ์šฉ/long polling ์‚ฌ์šฉ ๋ชจ๋‘ ์ง€์›ํ•  ์ˆ˜ ์žˆ๋‹ค.

TCP Socket๊ณผ ๋‹ค๋ฅธ ์ ์€ ์ฒ˜์Œ ์ ‘์†์ด http request์˜ handshaking ๊ณผ์ •์„ ํ†ตํ•ด ์ด๋ฃจ์–ด์ง„๋‹ค๋Š” ์ ์ด๋‹ค. http request๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ์กด์˜ 80, 443 ํฌํŠธ๋กœ ์ ‘์†ํ•œ๋‹ค.


Socket.IO Function

socket.emit(eventName[, ...args][, ack])

  • eventName์˜ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค. args์— ์ „๋‹ฌํ•˜๊ณ ์ž ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•œ๋‹ค.
socket.emit("ferret", "tobi", (data) => {
  console.log(data); // data will be "woot"
});

// server:
//  io.on("connection", (socket) => {
//    socket.on("ferret", (name, fn) => {
//      fn("woot");
//    });
//  });

socket.send([...args][, ack])

  • emit๊ณผ์˜ ์ฐจ์ด์ ์€ eventName์ด ์—†๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. eventName์€ message๋กœ ๊ณ ์ •๋˜์–ด `emit(โ€œmessageโ€,[..args])์™€ ๊ฐ™์€ ์—ญํ• ์„ ํ•œ๋‹ค.

socket.on(eventName, callback)

  • emit์œผ๋กœ ๋ฐœ์ƒ์‹œํ‚จ eventName์˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋“ฑ๋กํ•œ๋‹ค.
socket.on("news", (data) => {
  console.log(data);
});

// with multiple arguments
socket.on("news", (arg1, arg2, arg3, arg4) => {
  // ...
});
// with callback
socket.on("news", (cb) => {
  cb(0);
});

socket.once(eventName, callback)

  • eventName์˜ ์ผํšŒ์„ฑ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์ด๋‹ค. ๋‹ค์Œ์— ํ•œ๋ฒˆ ๋” eventName ์ด๋ฒคํŠธ๊ฐ€ ํŠธ๋ฆฌ๊ฑฐ๋˜๋ฉด ์ด ๋ฆฌ์Šค๋„ˆ๊ฐ€ ์ œ๊ฑฐ๋œ ๋‹ค์Œ ํ˜ธ์ถœ๋œ๋‹ค.
    socket.once("my-event", () => {
    // ...
    });
    

socket.onAny(callback)

  • eventName๊ณผ ์ƒ๊ด€์—†์ด ํฌ๊ด„์ ์œผ๋กœ ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•œ๋‹ค. ๋ชจ๋“  ์ด๋ฒคํŠธ๊ฐ€ ์ˆ˜์‹ ๋  ๋•Œ๋งˆ๋‹ค ์ž‘๋™ํ•œ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด event์— ์ˆ˜์‹ ํ•œ ์ด๋ฒคํŠธ์˜ eventName์ด ํ• ๋‹น๋˜๊ณ , args์— ์ˆ˜์‹ ํ•œ ์ด๋ฒคํŠธ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ํ• ๋‹น๋œ๋‹ค. webSocket์˜ onMessage์™€ ๊ฐ™์€ ์—ญํ• ์„ ํ•œ๋‹ค.
    socket.onAny((event, ...args) => {
    console.log(`got ${event}`);
    });
    


Socket.IO ์‚ฌ์šฉ๋ฒ•

๊ฐ„๋‹จํ•œ Client, Server ์˜ˆ์ œ๋กœ ์š”์ฒญ/์‘๋‹ต์„ ์ฃผ๊ณ ๋ฐ›๋Š” ์ฝ”๋“œ์ด๋‹ค.

Client ์ธก

1. socket.io ๊ฐ์ฒด ์ƒ์„ฑ

const io = require("socket.io-client");

const socketClient = io("http://127.0.0.1:20111");

๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์—ฐ๊ฒฐํ•  ์„œ๋ฒ„๋ฅผ ์„ค์ •ํ•œ๋‹ค.

2. ์—ฐ๊ฒฐ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ

socketClient.on("connect",()=>{
    console.log("Connect server by Socket.io");
});

์—ฐ๊ฒฐ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์œ„์™€ ๊ฐ™์€ ๋ฌธ๊ตฌ๋ฅผ ์ฝ˜์†” ์ฐฝ์— ์ถœ๋ ฅํ•œ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

  • connect: ์—ฐ๊ฒฐ ์„ฑ๊ณต
  • disconnect: ์—ฐ๊ฒฐ ์ข…๋ฃŒ
  • error: ์—๋Ÿฌ ๋ฐœ์ƒ
  • ์‚ฌ์šฉ์ž ์ •์˜ ์ด๋ฒคํŠธ

3. ์ด๋ฒคํŠธ ๋ฐœ์ƒ

socketClient.emit("request",{data:"Send Request"});

emit ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ request ์ด๋ฆ„๊ณผ Send Request ๋‚ด์šฉ์„ ๋‹ด์€ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

4. response ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ

socketClient.on("response",req =>{
    console.log(req);
});

response๋ผ๋Š” ์ด๋ฆ„์˜ ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์•˜์„ ๋•Œ ํ•ด๋‹น ์ด๋ฒคํŠธ์˜ ๋‚ด์šฉ์„ req๋กœ ๋ฐ›์•„์„œ ์ฝ˜์†” ์ฐฝ์— ์ถœ๋ ฅํ•œ๋‹ค.

OUTPUT

Connect server by Socket.io
{ data: 'Recieve Respond' }

Server ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๋ฉด ์œ„์™€ ๊ฐ™์ด ์„œ๋ฒ„ ์ธก์—์„œ ๋ณด๋‚ธ ์‘๋‹ต์ด ์ถœ๋ ฅ๋œ๋‹ค.


Server ์ธก

1. http ์„œ๋ฒ„, socket.io ๊ฐ์ฒด ์ƒ์„ฑ

const http = require('http');
const io = require("socket.io");

const httpServer = new http.Server();
const socketServer = io(httpServer);

socket.io ๊ฐ์ฒด์— ์—ฐ๊ฒฐํ•  http ์„œ๋ฒ„๋ฅผ ์„ค์ •ํ•œ๋‹ค.

2. http ์„œ๋ฒ„ ๊ตฌ๋™

httpServer.listen(20111, '127.0.0.1', () => {
    console.log('socket server listend: ', `http://127.0.0.1:20111`);
});

client์—์„œ ์„ค์ •ํ•œ ๋™์ผํ•œ ํฌํŠธ ๋ฒˆํ˜ธ์™€ ๊ฒฝ๋กœ๋ฅผ ์„ค์ •ํ•ด socket ์—ฐ๊ฒฐ์„ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.

3. ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ


socketServer.on('connection', socket => {
    console.log("Connect client by Socket.io");
    
    socket.on("request", req => {
        console.log(req);
        socket.emit("response", { data: "Send Respond" });
    });
});

client์™€ ์—ฐ๊ฒฐ๋˜๋ฉด Connect client by Socket.io๋ฅผ ์ฝ˜์†”์ฐฝ์— ์ถœ๋ ฅํ•œ๋‹ค. request ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์œผ๋ฉด ํ•ด๋‹น ๋‚ด์šฉ์„ ์ฝ˜์†” ์ฐฝ์— ์ถœ๋ ฅํ•˜๊ณ  ์ž˜๋ฐ›์•˜๋‹ค๋Š” ์ด๋ฒคํŠธ์ธ response๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

OUTPUT

socket server listend:  http://127.0.0.1:20111

server ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์•„์ง client ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ์œ„์™€ ๊ฐ™์ด listen์„ ์‹คํ–‰ํ•œ ์ฝ”๋“œ๋งŒ ์ถœ๋ ฅ๋œ๋‹ค.

Connect client by Socket.io
{ data: 'Send Request' }

client์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์œ„์™€ ๊ฐ™์ด ์ˆ˜์‹ ํ•œ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•œ ์ฝ”๋“œ๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค.


client.js ์ „์ฒด ์ฝ”๋“œ

const io = require("socket.io-client");

const socketClient = io("http://127.0.0.1:20111");

socketClient.on("connect",()=>{
    console.log("Connect server by Socket.io");
});

socketClient.emit("request",{data:"Send Request"});

socketClient.on("response",req =>{
    console.log(req);
});

server.js ์ „์ฒด ์ฝ”๋“œ

const http = require('http');
const io = require("socket.io");

const httpServer = new http.Server();
const socketServer = io(httpServer);

httpServer.listen(20111, '127.0.0.1', () => {
    console.log('socket server listend: ', `http://127.0.0.1:20111`);
});

socketServer.on('connection', socket => {
    console.log("Connect client by Socket.io");
    
    socket.on("request", req => {
        console.log(req);
        socket.emit("response", { data: "Recieve Respond" });
    });
});


Reference