Skip to content

๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ ๋‹ค์ค‘ ํƒญ์—์„œ ํ•˜๋‚˜์˜ ์†Œ์ผ“์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

I3KAE edited this page Dec 5, 2024 · 2 revisions

Why?

ํ˜„์žฌ ์ฑ„ํŒ… ๊ธฐ๋Šฅ์˜ ๋กœ์ง์€ ์ด๋Ÿฌํ•˜๋‹ค

  1. ์ฑ„ํŒ… ์ปดํฌ๋„ŒํŠธ ๋งˆ์šดํŠธ
  2. ์„œ๋ฒ„ ์†Œ์ผ“๊ณผ connection์„ ์œ„ํ•œ ์ƒˆ๋กœ์šด ์†Œ์ผ“ ์ƒ์„ฑ
  3. userId, sessionId๋ฅผ ์•Œ๊ณ  ์žˆ๋Š” ์ƒํƒœ์—์„œ join_room ์‹œ๋„
  4. ์„œ๋ฒ„์—์„œ userId๋ฅผ ํ† ๋Œ€๋กœ ๊ฒ€์ฆ ํ›„ ์ฑ„ํŒ… ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ์ „์†ก

์ฒ˜์Œ ์ฑ„ํŒ… ๊ธฐ๋Šฅ์„ ์„ค๊ณ„ํ•  ๋•Œ๋„ ๊ณ ๋ฏผํ–ˆ๋˜ ์ง€์ ์€ ๋งค๋ฒˆ ๋งˆ์šดํŠธ&์–ธ๋งˆ์šดํŠธ ์‹œ์— ์†Œ์ผ“์„ ์ƒ์„ฑํ•ด connectํ•˜๊ณ  disconnect๋ฅผ ๋ฐ˜๋ณตํ•˜๋Š” ๋ถ€๋ถ„์ด์—ˆ๋‹ค.

userId๋Š” ๊ณ ์œ ํ•˜์ง€๋งŒ ์‚ฌ์šฉ์ž๊ฐ€ ์—ฌ๋Ÿฌํƒญ์œผ๋กœ ์ž…์žฅํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ํ•˜๋‚˜์˜ userId์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ socket์ด ์—ฐ๊ฒฐ๋œ๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๊ณ , ์ด๋กœ์ธํ•ด ๋ถˆํ•„์š”ํ•œ ์†Œ์ผ“ ์—ฐ๊ฒฐ์ด ๋Š˜์–ด๋‚˜ ์„œ๋ฒ„์˜ ๋ฆฌ์†Œ์Šค ๋‚ญ๋น„๋ฅผ ๋ถˆ๋Ÿฌ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒฐ๋ก ์ด ๋‚˜์™”๋‹ค.

https://www.youtube.com/watch?v=SVt1-Opp3Wo

๊ทธ๋Ÿฌ๋˜ ์ค‘ ํ† ์Šค์—์„œ๋„ ๊ฐ™์€ ๊ณ ๋ฏผ์„ ํ–ˆ์—ˆ์œผ๋ฉฐ ํ•ด๋‹น ์˜์ƒ์˜ ์ธ์‚ฌ์ดํŠธ๋ฅผ ํ†ตํ•ด ํ•˜๋‚˜์˜ userId์— ๋Œ€ํ•œ ํ•˜๋‚˜์˜ ์†Œ์ผ“์œผ๋กœ ๊ฐœ์„ ํ•ด๋ณด๊ธฐ๋กœ ๊ฒฐ์ •ํ•˜์˜€๋‹ค.

How?

๋ธŒ๋ผ์šฐ์ € ํƒญ๋“ค์ด ํ•˜๋‚˜์˜ ์ƒํƒœ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋„๋กํ•˜๋Š” ์™ธ๋ถ€์˜ ๋ฌด์–ธ๊ฐ€๊ฐ€ ํ•„์š”ํ–ˆ๋‹ค

๊ทธ๋ฆฌ๊ณ  Web Worker API๋Š” ๊ทธ ์—ญํ• ์„ ํ•ด ์ค„ ์ˆ˜ ์žˆ์—ˆ๋‹ค!

Shared Worker Thread

image

SharedWorkerThread์— ์†Œ์ผ“ ๋„ฃ๊ณ  ๊ณต์œ ํ•ด๋ณด๊ธฐ

https://velog.io/@typo/sharing-websocket-connections-betwwen-tabs-and-windows

๊ธฐ์กด ๋ ˆํผ๋Ÿฐ์Šค๋“ค์€ ๋ฆฌ์•กํŠธ + ์›นํŒฉ๊ณผ WS ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์ ์—์„œ ์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ์™€ ๋‹ค๋ฅธ ๋ถ€๋ถ„๋“ค์ด ์žˆ์—ˆ๋‹ค.

ํด๋ผ์ด์–ธํŠธ์™€ sharedWorker๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๊ณผ์ •์€ ์‰ฝ๊ฒŒ ๋  ๊ฒƒ์ด๋ผ ์ƒ๊ฐํ–ˆ์ง€๋งŒ.. ์ƒ๊ฐ๋ณด๋‹ค ๋งŽ์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.

worker.ts ์Šคํฌ๋ฆฝํŠธ

์›Œ์ปค์˜ ๋‚ด๋ถ€ ๋™์ž‘์„ ์ž‘์„ฑํ•œ ์Šคํฌ๋ฆฝํŠธ์ด๋‹ค. ts์˜ ๊ฒฝ์šฐ ๋ฅผ ์ž‘์„ฑํ•ด์ฃผ์–ด์•ผ ์›Œ์ปค๊ด€๋ จ ํƒ€์ž…๊ณผ ๋ฉ”์„œ๋“œ๋ฅผ ์ธ์‹ํ•ด์ค€๋‹ค.

/// <reference lib="webworker" />

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

// ์†Œ์ผ“ ์—ฐ๊ฒฐ
const socket = io("http://localhost:8080"); // ์„œ๋ฒ„ URL
const ports: MessagePort[] = [];

self.onconnect = (e: MessageEvent) => {
  const port = e.ports[0];
  ports.push(port);

  // ํด๋ผ์ด์–ธํŠธ์—์„œ ์˜ค๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ์†Œ์ผ“ ์„œ๋ฒ„๋กœ ์ „๋‹ฌ
  port.onmessage = (messageEvent) => {
    const { message } = messageEvent.data;
    console.log("Received message in SharedWorker:", message);

    // ์„œ๋ฒ„๋กœ ๋ฉ”์‹œ์ง€ ์ „์†ก
    socket.emit("send_normal_chat", { msg: message });
  };

  // ์†Œ์ผ“์—์„œ ์˜ค๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ๋ชจ๋“  ํƒญ์— ์ „๋‹ฌ
  socket.on("message", (msg: string) => {
    ports.forEach((p) => p.postMessage({ message: msg }));
  });
};

export const test = 0;

Shared Worker ์ƒ์„ฑ

https://ko.vite.dev/guide/features#web-workers

1์ฐจ ์‹œ๋„: ์—ฌ๋Ÿฌ ๋ ˆํผ๋Ÿฐ์Šค์—์„œ ์ง„ํ–‰ํ•˜๋Š” ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•œ ์›Œ์ปค ์ƒ์„ฑ์„ ์ง„ํ–‰ํ•˜์˜€๋‹ค.

import { useEffect, useState } from "react";

const App = () => {
  const [worker, setWorker] = useState<SharedWorker | null>(null);
  const [message, setMessage] = useState<string>("");

  // App.tsx์—์„œ worker.ts๋ฅผ ๋™์ ์œผ๋กœ import
  useEffect(() => {
    const worker = new SharedWorker(new URL("./worker.ts", import.meta.url));

    // worker๊ฐ€ ์ค€๋น„๋˜๋ฉด ๋ฉ”์‹œ์ง€ ์ „์†ก
    worker.port.onmessage = (event) => {
      console.log("Received message from worker:", event.data.message);
      setMessage(event.data.message);
    };

    worker.port.start();

    // ์ดˆ๊ธฐ ๋ฉ”์‹œ์ง€ ์ „์†ก
    worker.port.postMessage({ message: "Hello from React!" });

    setWorker(worker);

    return () => {
      worker.port.close();
    };
  }, []);

ํ•˜์ง€๋งŒ ๊ณ„์†ํ•ด์„œ socket ์ƒ์„ฑ๋„ ๋˜์ง€ ์•Š๊ณ  port์™€ ์—ฐ๊ฒฐ์ด ๋˜์ง€ ์•Š๋Š” ๋ชจ์Šต์ด ๋ณด์˜€๊ณ , ๋ธŒ๋ผ์šฐ์ €์˜ ์†Œ์Šค์ฝ”๋“œ ํŒŒ์ผ์„ ํ™•์ธํ•ด๋ณธ ๊ฒฐ๊ณผ worker ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์˜ฌ๋ผ๊ฐ€์ง€ ์•Š๋Š” ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌ

์ด๋Š” vite์˜ ํŠธ๋ฆฌ์‰์ดํ‚น ๋ฌธ์ œ๋กœ import๋กœ ๊ฐ€์ ธ์˜ค์ง€ ์•Š์€ ์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์ด์—ˆ์œผ๋ฏ€๋กœ ๋นŒ๋“œ ๊ณผ์ •์—์„œ ์˜ฌ๋ผ๊ฐ€์ง€ ๋ชปํ–ˆ๊ณ  ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์—†๋Š” SharedWorker๊ฐ€ ์ƒ์„ฑ๋˜๊ฒŒ ๋œ๊ฒƒ์ด๋‹ค.

โ‡’ ๋ฉ˜ํ† ๋‹˜: ์ž˜๋ชป๋๋‹ค. ๋ธŒ๋ผ์šฐ์ €์— ์–ด๋–ป๊ฒŒ ์˜ฌ๋ผ๊ฐ€๋А๋ƒ๋ฅผ ์•Œ์•„๋ณด์ž


โ—๏ธํ•ด๋‹น ๋ฌธ์ œ์˜ ์›์ธ๊ณผ ํ•ด๊ฒฐ

์ฒ˜์Œ์—๋Š” ๋‹จ์ˆœํžˆ ํŠธ๋ฆฌ์‰์ดํ‚น์œผ๋กœ import ๋ฌธ์ด ์—†์–ด์„œ ์†Œ์Šค์— ํŒŒ์ผ์ด ๋“ค์–ด์˜ค์ง€ ๋ชปํ–ˆ๋‚˜? ๋ผ๋Š” ๋‡Œํ”ผ์…œ์„ ๋งˆ๊ตฌ๋งˆ๊ตฌ ์ ์–ด๋‘์—ˆ๋‹คโ€ฆ ํ•˜์ง€๋งŒ ์ด๋Š” ์ „ํ˜€ ๋ฌด๊ด€ํ•˜๋‹ค!

ํŠธ๋ฆฌ ์…ฐ์ดํ‚น์€ ๋ฒˆ๋“ค๋ง ๋‹จ๊ณ„์—์„œ ๋ถˆํ•„์š”ํ•œ ์ฝ”๋“œ(์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๋ชจ๋“ˆ)๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ์ตœ์ ํ™” ๊ณผ์ •์œผ๋กœ, ์›Œ์ปค ํŒŒ์ผ์˜ ์‹คํ–‰ ๋ฐฉ์‹์ด๋‚˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ์˜ ๋™์ž‘๊ณผ๋Š” ์ง์ ‘์ ์ธ ๊ด€๊ณ„๊ฐ€ ์—†๋‹ค.

const worker = new SharedWorker(new URL('/src/utils/chatWorker.ts', import.meta.url), { type: 'module' });

1. SharedWorker์˜ ์ž‘๋™ ๋ฐฉ์‹

  • SharedWorker๋Š” JavaScript ํŒŒ์ผ์„ ์›Œ์ปค ์Šค๋ ˆ๋“œ๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๋Š” ์›Œ์ปค๋ฅผ ์‹คํ–‰ํ•  ๋•Œ ํ•ด๋‹น ํŒŒ์ผ์„ ๊ฐ€์ ธ์™€ ์‹คํ–‰ํ•˜์ง€๋งŒ, ์›Œ์ปค๊ฐ€ ๋ชจ๋“ˆ๋กœ ์ž‘์„ฑ๋˜์—ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ์•Œ์•„์•ผ ์ ์ ˆํžˆ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • type: 'module'์„ ์ง€์ •ํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๋Š” ํ•ด๋‹น ์›Œ์ปค ํŒŒ์ผ์„ ES ๋ชจ๋“ˆ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • ES ๋ชจ๋“ˆ๋กœ ์ฒ˜๋ฆฌํ•˜๋ฉด ๋‹ค์Œ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค:
    1. ํŒŒ์ผ ๋‚ด๋ถ€์—์„œ import/export๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ.
    2. ํŒŒ์ผ ์Šค์ฝ”ํ”„๊ฐ€ ๋…๋ฆฝ์ ์ž„.

2. ์™œ type: 'module'์„ ๋ถ™์—ฌ์•ผ ํ•˜๋‚˜?

Vite๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ES ๋ชจ๋“ˆ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•˜๋ฉฐ, ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ชจ๋“ˆ ๋ฐฉ์‹์œผ๋กœ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋„๋ก ๋ฒˆ๋“ค๋งํ•ฉ๋‹ˆ๋‹ค.

๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํŒŒ์ผ์„ ๋กœ๋“œํ•˜๋Š” ๊ณผ์ •:

  • ๋ธŒ๋ผ์šฐ์ €๋Š” SharedWorker์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ ๋ฐ›์€ ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์œผ๋กœ ๋ฐ›์•„์˜ต๋‹ˆ๋‹ค.
  • ์š”์ฒญํ•œ ํŒŒ์ผ์ด ์ผ๋ฐ˜ ์Šคํฌ๋ฆฝํŠธ(type: "classic")๋กœ ์ฒ˜๋ฆฌ๋˜๋ฉด, ํŒŒ์ผ ๋‚ด์šฉ์ด ์ „์—ญ ์Šค์ฝ”ํ”„์—์„œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
  • ์š”์ฒญํ•œ ํŒŒ์ผ์ด ๋ชจ๋“ˆ ์Šคํฌ๋ฆฝํŠธ(type: "module")๋กœ ์ฒ˜๋ฆฌ๋˜๋ฉด, ๋ธŒ๋ผ์šฐ์ €๋Š” ์ด๋ฅผ ESM์œผ๋กœ ์‹คํ–‰ํ•˜๋ฉฐ, ๋ชจ๋“ˆ ์‚ฌ์–‘์— ๋งž๋Š” ํ™˜๊ฒฝ์—์„œ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ, SharedWorker ํŒŒ์ผ์ด ๋ชจ๋“ˆ๋กœ ์ž‘์„ฑ๋˜์—ˆ๋‹ค๋ฉด type: 'module'์„ ์ง€์ •ํ•ด์•ผ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ด๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


3. Vite์˜ ๋ฒˆ๋“ค๋ง ๊ณผ์ •๊ณผ type: 'module์˜ ๊ด€๊ณ„

Vite์˜ ๋™์ž‘ ๋ฐฉ์‹:

  1. ํŒŒ์ผ ๋ณ€ํ™˜:
    • Vite๋Š” TypeScript ํŒŒ์ผ(.ts)์„ JavaScript ํŒŒ์ผ(.js)๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    • ES6 ์ด์ƒ์˜ ๋ชจ๋“ˆ ์‚ฌ์–‘์— ๋”ฐ๋ผ ๋ฒˆ๋“ค๋งํ•ฉ๋‹ˆ๋‹ค.
    • import.meta.url์€ Vite๊ฐ€ ์ฒ˜๋ฆฌํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ €์—์„œ ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  2. ํŒŒ์ผ ์ œ๊ณต:
    • ๊ฐœ๋ฐœ ์„œ๋ฒ„ ๋ชจ๋“œ์—์„œ Vite๋Š” ํŒŒ์ผ์„ ๋ฒˆ๋“ค๋งํ•˜์ง€ ์•Š๊ณ  ์˜จ๋””๋งจ๋“œ๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
    • ๋ธŒ๋ผ์šฐ์ €๊ฐ€ new URL('/src/utils/chatWorker.ts', import.meta.url)์„ ์š”์ฒญํ•˜๋ฉด Vite๋Š” ํ•ด๋‹น ํŒŒ์ผ์„ ๋™์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    • ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ์—์„œ๋Š” Vite๊ฐ€ ์›Œ์ปค ํŒŒ์ผ์„ ๋ณ„๋„ ๋ฒˆ๋“ค๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ์ œ๊ณตํ•˜๋ฉฐ, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ด ํŒŒ์ผ์„ ์ ์ ˆํžˆ ๋กœ๋“œํ•˜๋„๋ก ๊ฒฝ๋กœ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  3. ๋ชจ๋“ˆ ์ง€์›:
    • Vite๋Š” ์›Œ์ปค ํŒŒ์ผ์„ ๊ธฐ๋ณธ์ ์œผ๋กœ ES ๋ชจ๋“ˆ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
    • ์›Œ์ปค๋ฅผ type: 'module'๋กœ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ๋ธŒ๋ผ์šฐ์ €๋Š” ์ด๋ฅผ ์ผ๋ฐ˜ ์Šคํฌ๋ฆฝํŠธ๋กœ ์ฒ˜๋ฆฌํ•˜๋ ค๊ณ  ํ•˜๋ฉฐ, ์ด ๊ฒฝ์šฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

4. type: 'module'์ด ์—†์„ ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ

๋ฌธ์ œ:

  • ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์›Œ์ปค ํŒŒ์ผ์„ ์ผ๋ฐ˜ ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•˜๋ ค๊ณ  ์‹œ๋„.

  • Vite๊ฐ€ ๋ฒˆ๋“ค๋งํ•œ ๊ฒฐ๊ณผ ํŒŒ์ผ์€ ESM ์‚ฌ์–‘์— ๋”ฐ๋ผ ์ž‘์„ฑ๋˜๋ฏ€๋กœ ์ผ๋ฐ˜ ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Œ.

  • ์˜ˆ๋ฅผ ๋“ค์–ด, Vite๋Š” ์›Œ์ปค ํŒŒ์ผ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

    javascript
    ์ฝ”๋“œ ๋ณต์‚ฌ
    import { someFunction } from './someModule.js';
    someFunction();
  • ๋ธŒ๋ผ์šฐ์ €๋Š” ์ผ๋ฐ˜ ์Šคํฌ๋ฆฝํŠธ์—์„œ import๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์—๋Ÿฌ ๋ฐœ์ƒ:

    javascript
    ์ฝ”๋“œ ๋ณต์‚ฌ
    SyntaxError: Unexpected token 'import'

ํ•ด๊ฒฐ:

  • type: 'module'์„ ๋ช…์‹œํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๋Š” ํ•ด๋‹น ํŒŒ์ผ์„ ๋ชจ๋“ˆ๋กœ ์ฒ˜๋ฆฌํ•˜๊ณ , Vite๊ฐ€ ์ œ๊ณตํ•˜๋Š” ํŒŒ์ผ์„ ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰.

5. Vite๊ฐ€ ์ œ๊ณตํ•˜๋Š” URL ๋™์ž‘ ๋ฐฉ์‹

new URL('/src/utils/chatWorker.ts', import.meta.url)์€ ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์นฉ๋‹ˆ๋‹ค:

  1. Vite๋Š” import.meta.url์„ ํ†ตํ•ด ํ˜„์žฌ ๋ชจ๋“ˆ์˜ URL์„ ๊ณ„์‚ฐ.
  2. /src/utils/chatWorker.ts ๊ฒฝ๋กœ๋ฅผ ํ˜„์žฌ ๋ชจ๋“ˆ์˜ URL์„ ๊ธฐ์ค€์œผ๋กœ ํ•ด์„.
  3. ์›Œ์ปค ํŒŒ์ผ์„ http://localhost:3000/src/utils/chatWorker.ts์ฒ˜๋Ÿผ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ URL๋กœ ๋ณ€ํ™˜.
  4. ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ•ด๋‹น URL๋กœ ์š”์ฒญ์„ ๋ณด๋ƒ„.
  5. Vite ๊ฐœ๋ฐœ ์„œ๋ฒ„๊ฐ€ ํ•ด๋‹น ํŒŒ์ผ์„ ๋™์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์—ฌ ๋ฐ˜ํ™˜.

6. ๊ฒฐ๋ก 

  • type: 'module'์€ ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ ์›Œ์ปค ํŒŒ์ผ์ด ES ๋ชจ๋“ˆ์ž„์„ ์•Œ๋ ค์ฃผ๋Š” ์—ญํ• .
  • Vite๋Š” ํŒŒ์ผ์„ ๋ฒˆ๋“ค๋งํ•˜๊ฑฐ๋‚˜ ์ œ๊ณตํ•  ๋•Œ ES ๋ชจ๋“ˆ ํ˜•์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋ฏ€๋กœ, ์ด๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•ด์•ผ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋กœ๋“œ.
  • Vite์™€ ๋ธŒ๋ผ์šฐ์ €์˜ ๋ชจ๋“ˆ ๋™์ž‘์„ ๊ฒฐํ•ฉํ•œ ๊ฒฐ๊ณผ, type: 'module'์„ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด import/export ๊ด€๋ จ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒ.

2์ฐจ ์‹œ๋„

๋งˆ์ง€๋ง‰์œผ๋กœ vite ๊ณต์‹๋ฌธ์„œ์— ์ ํ˜€์žˆ๋˜ ๋‘๋ฒˆ์งธ import ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ด๋ณด์•˜๋‹ค.

์ฟผ๋ฆฌ ์ ‘๋ฏธ์‚ฌ ?workerย ๋˜๋Š”ย ?sharedworker๋ฅผ ์ด์šฉํ•ด ์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค

ํ•ด๋‹น ๋ฐฉ์‹์„ ํ†ตํ•ด ์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์€ ํŠธ๋ฆฌ์‰์ดํ‚น์ด ๋˜์ง€ ์•Š๊ณ  ์„ฑ๊ณต์ ์œผ๋กœ ์›Œ์ปค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค ใ…œใ…œ

import { useEffect, useState } from "react";
import MyWorker from "./worker?sharedworker";

const App = () => {
  const [worker, setWorker] = useState<SharedWorker | null>(null);
  const [message, setMessage] = useState<string>("");

  useEffect(() => {
    const worker = new MyWorker();

    console.log(worker);
    // worker๊ฐ€ ์ค€๋น„๋˜๋ฉด ๋ฉ”์‹œ์ง€ ์ „์†ก
    worker.port.onmessage = (event) => {
      console.log("Received message from worker:", event.data.message);
      setMessage(event.data.message);
    };

    worker.port.start();

    // ์ดˆ๊ธฐ ๋ฉ”์‹œ์ง€ ์ „์†ก
    worker.port.postMessage({ message: "Hello from React!" });

    setWorker(worker);

    return () => {
      worker.port.close();
    };
  }, []);

  const handleClick = () => {
    if (worker) {
      // ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ๋ฉ”์‹œ์ง€ ์ „์†ก
      worker.port.postMessage({ message: "Hello from React on button click!" });
    }
  };

  return (
    <div>
      <h1>React with Shared Worker and Socket.io</h1>
      <p>Received from worker: {message}</p>
      <button onClick={handleClick}>Send Message to Worker</button>
    </div>
  );
};

export default App;

image ์œ„๋Š” ํด๋ผ์ด์–ธํŠธ ํƒญ์„ 2๊ฐœ ๋„์› ์„๋•Œ์˜ ์„œ๋ฒ„ ๋กœ๊ทธ์ด๋‹ค.

์ฒ˜์Œ ํƒญ์ด ์—ด๋ ธ์„ ๋•Œ shared worker๋Š” ๊ณต์œ ๋  ์†Œ์ผ“ ํ•˜๋‚˜๋ฅผ ์ƒ์„ฑํ•œ๋‹ค (id: un19~)

๊ทธ๋ฆฌ๊ณ  ํƒญ์ผ ์—ด๋ ธ์„ ๋•Œ ํด๋ผ์ด์–ธํŠธ์—์„œ โ€œHello from Reactโ€๋ฅผ shared worker์—๊ฒŒ postMessage๋ฅผ ํ•˜๊ณ  worker๋Š” ๋ฐ›์€ ๋ฉ”์„ธ์ง€๋ฅผ ์ž์‹ ์˜ socket์„ ํ†ตํ•ด ์„œ๋ฒ„๋กœ ์ „์†กํ•œ๋‹ค.

๋‹ค๋ฅธ ํƒญ์„ ์—ด๋ ธ์„ ๋•Œ๋Š” ์ด๋ฏธ ์†Œ์ผ“์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ƒˆ๋กœ ์ƒ์„ฑ์ด ์ด๋ค„์ง€์ง€ ์•Š๊ณ  ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ์†Œ์ผ“์œผ๋กœ ๋˜๋‹ค์‹œ ์„œ๋ฒ„์— ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ธ ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•ด๋‹น ๊ณผ์ •์„ ์ข€๋” ํ™•์‹คํ•˜๊ฒŒ ๋ณด๊ณ ์ž port๊ฐ€ ์—ฐ๊ฒฐ๋  ๋•Œ๋งˆ๋‹ค ์นด์šดํŒ…์„ ํ•˜๊ณ  ๋กœ๊ทธ๋ฅผ ์ฐ์–ด๋ณด์•˜๋‹ค. image ์ƒˆ๋กœ์šด ํƒญ์„ ์—ด๊ฑฐ๋‚˜ ์ƒˆ๋กœ๊ณ ์นจ์„ ํ•  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ์†Œ์ผ“์ด ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ํ•˜๋‚˜์˜ ์†Œ์ผ“์„ ์—ฌ๋Ÿฌ ํฌํŠธ(ํƒญ)์—์„œ ๊ณต์œ ํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๋งŒ์•ฝ ํฌํŠธ(ํƒญ)์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ฒŒ๋œ๋‹ค๋ฉด ํฌํŠธ์— ๋Œ€ํ•œ ๊ณต๊ฐ„์„ ์ œ๊ฑฐํ•˜๋Š” ๋ฐฉ์‹์€ ๊ฐ€๋น„์ง€ ์ฝœ๋ ‰ํ„ฐ๋ฅผ ์ด์šฉํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. ํ›„์— ์•Œ์•„๋ณด์ž..

LiBoo

ํŒ€

๊ณตํ†ต

๋ฏผ์ง€

์˜๊ธธ

์ค€์„œ

์ง€์ˆ˜

์ฐฝํ˜„

๋ฐ์ผ๋ฆฌ ์Šคํฌ๋Ÿผ

ํšŒ์˜๋ก

๋ฐœํ‘œ

์ผ๊ธฐ์žฅ

Clone this wiki locally