๐Ÿ’ฌ socket.io๋กœ ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ… ๊ตฌํ˜„ํ•˜๊ธฐ

Yeonnยท2025๋…„ 3์›” 4์ผ
0

๊ธฐ๋Šฅ ๊ตฌํ˜„ํ•˜๊ธฐ

๋ชฉ๋ก ๋ณด๊ธฐ
2/10
post-thumbnail

๋ธŒ๋ผ์šฐ์ €์™€ ์„œ๋ฒ„ ๊ฐ„ ์–‘๋ฐฉํ–ฅ ์‹ค์‹œ๊ฐ„ ํ†ต์‹  ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

WebSocket์„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉ

๋ธŒ๋ผ์šฐ์ €๊ฐ€ WebSocket์„ ์ง€์›ํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ Long Polling ๋“ฑ์˜ ๋Œ€์ฒด ๊ธฐ์ˆ  ์ž๋™ ์ ์šฉ โ†’ ์•ˆ์ •์„ฑ ํ™•๋ณด

โ“ ๊ธฐ์กด HTTP ํ†ต์‹ ๊ณผ์˜ ์ฐจ์ด์ 

  • ๊ธฐ์กด HTTP ์š”์ฒญ-์‘๋‹ต ๋ฐฉ์‹
    • ๋ธŒ๋ผ์šฐ์ € โ†’ ์„œ๋ฒ„ ์š”์ฒญ
    • ์„œ๋ฒ„ โ†’ ๋ธŒ๋ผ์šฐ์ € ์‘๋‹ต
    • ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฐ˜๋ณตํ•ด์„œ ์š”์ฒญ(Polling)
  • socket.io
    • ์—ฐ๊ฒฐ์„ ์œ ์ง€ํ•˜๋ฉด์„œ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๊ฐ€ ์ž์œ ๋กญ๊ฒŒ ๋ฐ์ดํ„ฐ ์†ก์ˆ˜์‹  ๊ฐ€๋Šฅ!
    • ์„œ๋ฒ„ โ†’ ํด๋ผ์ด์–ธํŠธ ๋ฐ์ดํ„ฐ Push ๊ฐ€๋Šฅ
    • ํด๋ผ์ด์–ธํŠธ โ†’ ์„œ๋ฒ„ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ๋ฉ”์‹œ์ง€ ์ „์†ก ๊ฐ€๋Šฅ
    • ์ž๋™ ์žฌ์—ฐ๊ฒฐ ์ง€์› (๋ชจ๋ฐ”์ผ ๋„คํŠธ์›Œํฌ ๋ณ€ํ™”์—๋„ ๊ฐ•ํ•จ)
๐Ÿ’ก

์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…, ๊ฒŒ์ž„, ์•Œ๋ฆผ ์„œ๋น„์Šค ๊ฐ™์€ ์ง€์†์ ์ธ ๋ฐ์ดํ„ฐ ๊ตํ™˜์ด ํ•„์š”ํ•œ ์„œ๋น„์Šค์— ์ ํ•ฉ !


โ“ socket.io์˜ ํŠน์ง•

  • ์‹ค์‹œ๊ฐ„ ํ†ต์‹ 
    • ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‹ค์‹œ๊ฐ„ ์—…๋ฐ์ดํŠธ ๊ฐ€๋Šฅ
    • ex) ์ฑ„ํŒ…, ์ฃผ์‹ ๊ฑฐ๋ž˜ ํ”Œ๋žซํผ, ๊ฒŒ์ž„, ๋ผ์ด๋ธŒ ์Šค์ฝ”์–ด ๋ณด๋“œ ๋“ฑ
  • ์ž๋™ ์žฌ์—ฐ๊ฒฐ / ํด๋ฐฑ(Fallback) ์ง€์›
    • ๋„คํŠธ์›Œํฌ๊ฐ€ ๋Š์–ด์กŒ๋‹ค๊ฐ€ ๋‹ค์‹œ ์—ฐ๊ฒฐ๋˜๋ฉด ์ž๋™ ๋ณต๊ตฌ
    • WebSocket์ด ๋ถˆ๊ฐ€๋Šฅํ•œ ํ™˜๊ฒฝ์—์„œ๋Š” Long Polling์„ ์‚ฌ์šฉํ•˜์—ฌ ์—ฐ๊ฒฐ ์œ ์ง€
  • ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ๋ฉ”์‹œ์ง€ ์†ก์ˆ˜์‹ 
    • emit()๊ณผ on()์„ ์‚ฌ์šฉํ•ด ํŠน์ • ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ ์ฃผ๊ณ ๋ฐ›๊ธฐ ๊ฐ€๋Šฅ
  • Rooms & Namespaces ์ง€์›
    • ํŠน์ • ๊ทธ๋ฃน ์œ ์ €์—๊ฒŒ๋งŒ ๋ฉ”์‹œ์ง€ ๋ณด๋‚ด๋Š” Rooms
    • ๊ธฐ๋Šฅ๋ณ„๋กœ ์„œ๋ฒ„๋ฅผ ๋‚˜๋ˆ„๋Š” Namespaces ์ง€์›

โ—๏ธ ๋ธŒ๋ผ์šฐ์ €์—์„œ socket.io ์‚ฌ์šฉํ•˜๊ธฐ

1. socket.io ์„ค์น˜

npm install socket.io-client

2. socket.io ์—ฐ๊ฒฐ

import { io } from "socket.io-client";

const socket = io("https://example.com"); 

socket.on("connect", () => {
  console.log("โœ… Socket.io ์—ฐ๊ฒฐ ์„ฑ๊ณต!");
});

3. ์„œ๋ฒ„์™€ ๋ฐ์ดํ„ฐ ์ฃผ๊ณ ๋ฐ›๊ธฐ: emit() on()

๐Ÿ“ค ํด๋ผ์ด์–ธํŠธ โ†’ ์„œ๋ฒ„ (์ด๋ฒคํŠธ ์ „์†ก)

// socket.emit("์ด๋ฒคํŠธ ์ด๋ฆ„", ํ•ด๋‹น ์ด๋ฒคํŠธ์™€ ๋ณด๋‚ผ ๋ฐ์ดํ„ฐ)
socket.emit("message", "Hello Server!");

๐Ÿ“ฅ ์„œ๋ฒ„ โ†’ ํด๋ผ์ด์–ธํŠธ (์ด๋ฒคํŠธ ์ˆ˜์‹ )

// socket.on("์ด๋ฒคํŠธ ์ด๋ฆ„", ํ•ด๋‹น ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•  ํ•จ์ˆ˜)
socket.on("message", (data) => {
  console.log("๐Ÿ“ฉ ์„œ๋ฒ„์—์„œ ๋ฐ›์€ ๋ฉ”์‹œ์ง€:", data);
});

4. ์†Œ์ผ“ ์—ฐ๊ฒฐ ์ข…๋ฃŒ

socket.on("disconnect", () => {
  console.log("๐Ÿšซ ์—ฐ๊ฒฐ์ด ์ข…๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");
});

socket.disconnect(); // ์—ฐ๊ฒฐ ๋Š๊ธฐ

๐Ÿš€ย WebSocket API vs socket.io

WebSocket APIsocket.io
์—ฐ๊ฒฐ ๋ฐฉ์‹new WebSocket(url)io(url)
๋ฉ”์‹œ์ง€ ์ „์†กsocket.send(data)socket.emit(event, data)
์ด๋ฒคํŠธonopen onmessage onclose onerroron('connect') on('disconnect') on('message')
์ž๋™ ์žฌ์—ฐ๊ฒฐ์ง์ ‘ ๊ตฌํ˜„ ํ•„์š”๊ธฐ๋ณธ ์ง€์›
Rooms & Namespaces์ง์ ‘ ๊ตฌํ˜„ ํ•„์š”๊ธฐ๋ณธ ์ œ๊ณต
Fallback ์ง€์›์ง€์› ์•ˆ ํ•จWebSocket์ด ์•ˆ ๋˜๋Š” ๊ฒฝ์šฐ Long Polling ์‚ฌ์šฉ

โœ”๏ธย ์‹ค์ œ ํ™œ์šฉ ์˜ˆ์‹œ

const getChatRooms = useCallback(() => {
    socket.emit("getChatRooms");
  }, [chatRoomId]);

useEffect(() => {
  if (!socket) return;

  getChatRooms();

  const handleChatRooms = (rooms: ChatRooms[]) => {
    setChats(rooms);
  };

  socket.on("chatRooms", handleChatRooms);

  return () => {
    socket.off("chatRooms", handleChatRooms);
    // socket.off("์ด๋ฒคํŠธ๋ช…")์€ ํ•ด๋‹น ์ด๋ฒคํŠธ์˜ ๋ชจ๋“  ๋ฆฌ์Šค๋„ˆ๋ฅผ ์ œ๊ฑฐ
    // ํŠน์ • ํ•ธ๋“ค๋Ÿฌ๋งŒ ์ œ๊ฑฐํ•˜๋ ค๋ฉด ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ•จ๊ป˜ ์ „๋‹ฌ
  };
}, [socket]);

0๊ฐœ์˜ ๋Œ“๊ธ€