-
Notifications
You must be signed in to change notification settings - Fork 4
๐จโ๐ฉโ๐งโ๐ฆ ๋ค์ค ํญ์์ ํ๋์ ์์ผ์ ๊ณต์ ํ ์ ์์๊น?
ํ์ฌ ์ฑํ ๊ธฐ๋ฅ์ ๋ก์ง์ ์ด๋ฌํ๋ค
- ์ฑํ ์ปดํฌ๋ํธ ๋ง์ดํธ
- ์๋ฒ ์์ผ๊ณผ connection์ ์ํ ์๋ก์ด ์์ผ ์์ฑ
- userId, sessionId๋ฅผ ์๊ณ ์๋ ์ํ์์ join_room ์๋
- ์๋ฒ์์ userId๋ฅผ ํ ๋๋ก ๊ฒ์ฆ ํ ์ฑํ ๊ฐ๋ฅ ์ฌ๋ถ ์ ์ก
์ฒ์ ์ฑํ ๊ธฐ๋ฅ์ ์ค๊ณํ ๋๋ ๊ณ ๋ฏผํ๋ ์ง์ ์ ๋งค๋ฒ ๋ง์ดํธ&์ธ๋ง์ดํธ ์์ ์์ผ์ ์์ฑํด connectํ๊ณ disconnect๋ฅผ ๋ฐ๋ณตํ๋ ๋ถ๋ถ์ด์๋ค.
userId๋ ๊ณ ์ ํ์ง๋ง ์ฌ์ฉ์๊ฐ ์ฌ๋ฌํญ์ผ๋ก ์ ์ฅํ๊ฒ ๋๋ค๋ฉด ํ๋์ userId์ ๋ํ ์ฌ๋ฌ socket์ด ์ฐ๊ฒฐ๋๋ค๋ ๋ฌธ์ ๊ฐ ์์๊ณ , ์ด๋ก์ธํด ๋ถํ์ํ ์์ผ ์ฐ๊ฒฐ์ด ๋์ด๋ ์๋ฒ์ ๋ฆฌ์์ค ๋ญ๋น๋ฅผ ๋ถ๋ฌ์ผ์ผํฌ ์ ์๋ค๋ ๊ฒฐ๋ก ์ด ๋์๋ค.
https://www.youtube.com/watch?v=SVt1-Opp3Wo
๊ทธ๋ฌ๋ ์ค ํ ์ค์์๋ ๊ฐ์ ๊ณ ๋ฏผ์ ํ์์ผ๋ฉฐ ํด๋น ์์์ ์ธ์ฌ์ดํธ๋ฅผ ํตํด ํ๋์ userId์ ๋ํ ํ๋์ ์์ผ์ผ๋ก ๊ฐ์ ํด๋ณด๊ธฐ๋ก ๊ฒฐ์ ํ์๋ค.
๋ธ๋ผ์ฐ์ ํญ๋ค์ด ํ๋์ ์ํ๋ฅผ ๊ณต์ ํ ์ ์๋๋กํ๋ ์ธ๋ถ์ ๋ฌด์ธ๊ฐ๊ฐ ํ์ํ๋ค
๊ทธ๋ฆฌ๊ณ Web Worker API๋ ๊ทธ ์ญํ ์ ํด ์ค ์ ์์๋ค!

https://velog.io/@typo/sharing-websocket-connections-betwwen-tabs-and-windows
๊ธฐ์กด ๋ ํผ๋ฐ์ค๋ค์ ๋ฆฌ์กํธ + ์นํฉ๊ณผ WS ๋ชจ๋์ ์ฌ์ฉํ๋ค๋ ์ ์์ ์ฐ๋ฆฌ ํ๋ก์ ํธ์ ๋ค๋ฅธ ๋ถ๋ถ๋ค์ด ์์๋ค.
ํด๋ผ์ด์ธํธ์ sharedWorker๋ฅผ ์ฐ๊ฒฐํ๋ ๊ณผ์ ์ ์ฝ๊ฒ ๋ ๊ฒ์ด๋ผ ์๊ฐํ์ง๋ง.. ์๊ฐ๋ณด๋ค ๋ง์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
์์ปค์ ๋ด๋ถ ๋์์ ์์ฑํ ์คํฌ๋ฆฝํธ์ด๋ค. 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;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' });- SharedWorker๋ JavaScript ํ์ผ์ ์์ปค ์ค๋ ๋๋ก ์คํํฉ๋๋ค. ๋ธ๋ผ์ฐ์ ๋ ์์ปค๋ฅผ ์คํํ ๋ ํด๋น ํ์ผ์ ๊ฐ์ ธ์ ์คํํ์ง๋ง, ์์ปค๊ฐ ๋ชจ๋๋ก ์์ฑ๋์๋์ง ์ฌ๋ถ๋ฅผ ์์์ผ ์ ์ ํ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
-
type: 'module'์ ์ง์ ํ๋ฉด ๋ธ๋ผ์ฐ์ ๋ ํด๋น ์์ปค ํ์ผ์ ES ๋ชจ๋๋ก ์ฒ๋ฆฌํฉ๋๋ค. - ES ๋ชจ๋๋ก ์ฒ๋ฆฌํ๋ฉด ๋ค์์ด ๊ฐ๋ฅํฉ๋๋ค:
- ํ์ผ ๋ด๋ถ์์
import/export๋ฅผ ์ฌ์ฉํ ์ ์์. - ํ์ผ ์ค์ฝํ๊ฐ ๋ ๋ฆฝ์ ์.
- ํ์ผ ๋ด๋ถ์์
Vite๋ ๊ธฐ๋ณธ์ ์ผ๋ก ES ๋ชจ๋์ ๊ธฐ๋ฐ์ผ๋ก ๋์ํ๋ฉฐ, ๋ธ๋ผ์ฐ์ ์์ ๋ชจ๋ ๋ฐฉ์์ผ๋ก ์คํฌ๋ฆฝํธ๋ฅผ ์ฒ๋ฆฌํ๋๋ก ๋ฒ๋ค๋งํฉ๋๋ค.
- ๋ธ๋ผ์ฐ์ ๋
SharedWorker์ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ๋ฐ์ ํ์ผ ๊ฒฝ๋ก๋ฅผ ๋คํธ์ํฌ ์์ฒญ์ผ๋ก ๋ฐ์์ต๋๋ค. - ์์ฒญํ ํ์ผ์ด ์ผ๋ฐ ์คํฌ๋ฆฝํธ(
type: "classic")๋ก ์ฒ๋ฆฌ๋๋ฉด, ํ์ผ ๋ด์ฉ์ด ์ ์ญ ์ค์ฝํ์์ ์คํ๋ฉ๋๋ค. - ์์ฒญํ ํ์ผ์ด ๋ชจ๋ ์คํฌ๋ฆฝํธ(
type: "module")๋ก ์ฒ๋ฆฌ๋๋ฉด, ๋ธ๋ผ์ฐ์ ๋ ์ด๋ฅผ ESM์ผ๋ก ์คํํ๋ฉฐ, ๋ชจ๋ ์ฌ์์ ๋ง๋ ํ๊ฒฝ์์ ์ฒ๋ฆฌํฉ๋๋ค.
๋ฐ๋ผ์, SharedWorker ํ์ผ์ด ๋ชจ๋๋ก ์์ฑ๋์๋ค๋ฉด type: 'module'์ ์ง์ ํด์ผ ๋ธ๋ผ์ฐ์ ๊ฐ ์ด๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
-
ํ์ผ ๋ณํ:
- Vite๋ TypeScript ํ์ผ(
.ts)์ JavaScript ํ์ผ(.js)๋ก ๋ณํํฉ๋๋ค. - ES6 ์ด์์ ๋ชจ๋ ์ฌ์์ ๋ฐ๋ผ ๋ฒ๋ค๋งํฉ๋๋ค.
-
import.meta.url์ Vite๊ฐ ์ฒ๋ฆฌํ์ฌ ๋ธ๋ผ์ฐ์ ์์ ํ์ผ ๊ฒฝ๋ก๋ฅผ ์ ์ ์๋๋ก ํฉ๋๋ค.
- Vite๋ TypeScript ํ์ผ(
-
ํ์ผ ์ ๊ณต:
- ๊ฐ๋ฐ ์๋ฒ ๋ชจ๋์์ Vite๋ ํ์ผ์ ๋ฒ๋ค๋งํ์ง ์๊ณ ์จ๋๋งจ๋๋ก ์ ๊ณตํฉ๋๋ค.
- ๋ธ๋ผ์ฐ์ ๊ฐ
new URL('/src/utils/chatWorker.ts', import.meta.url)์ ์์ฒญํ๋ฉด Vite๋ ํด๋น ํ์ผ์ ๋์ ์ผ๋ก ์ฒ๋ฆฌํ๊ณ ๋ฐํํฉ๋๋ค. - ํ๋ก๋์ ๋น๋์์๋ Vite๊ฐ ์์ปค ํ์ผ์ ๋ณ๋ ๋ฒ๋ค๋ก ๋ถ๋ฆฌํ์ฌ ์ ๊ณตํ๋ฉฐ, ๋ธ๋ผ์ฐ์ ๊ฐ ์ด ํ์ผ์ ์ ์ ํ ๋ก๋ํ๋๋ก ๊ฒฝ๋ก๋ฅผ ์ค์ ํฉ๋๋ค.
-
๋ชจ๋ ์ง์:
- Vite๋ ์์ปค ํ์ผ์ ๊ธฐ๋ณธ์ ์ผ๋ก ES ๋ชจ๋๋ก ์ฒ๋ฆฌํฉ๋๋ค.
- ์์ปค๋ฅผ
type: 'module'๋ก ์ง์ ํ์ง ์์ผ๋ฉด ๋ธ๋ผ์ฐ์ ๋ ์ด๋ฅผ ์ผ๋ฐ ์คํฌ๋ฆฝํธ๋ก ์ฒ๋ฆฌํ๋ ค๊ณ ํ๋ฉฐ, ์ด ๊ฒฝ์ฐ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
-
๋ธ๋ผ์ฐ์ ๊ฐ ์์ปค ํ์ผ์ ์ผ๋ฐ ์คํฌ๋ฆฝํธ๋ก ์คํํ๋ ค๊ณ ์๋.
-
Vite๊ฐ ๋ฒ๋ค๋งํ ๊ฒฐ๊ณผ ํ์ผ์ ESM ์ฌ์์ ๋ฐ๋ผ ์์ฑ๋๋ฏ๋ก ์ผ๋ฐ ์คํฌ๋ฆฝํธ๋ก ์คํํ ์ ์์.
-
์๋ฅผ ๋ค์ด, Vite๋ ์์ปค ํ์ผ์์ ๋ค์๊ณผ ๊ฐ์ ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ต๋๋ค:
javascript ์ฝ๋ ๋ณต์ฌ import { someFunction } from './someModule.js'; someFunction();
-
๋ธ๋ผ์ฐ์ ๋ ์ผ๋ฐ ์คํฌ๋ฆฝํธ์์
import๋ฅผ ์ง์ํ์ง ์์ผ๋ฏ๋ก ์๋ฌ ๋ฐ์:javascript ์ฝ๋ ๋ณต์ฌ SyntaxError: Unexpected token 'import'
-
type: 'module'์ ๋ช ์ํ๋ฉด ๋ธ๋ผ์ฐ์ ๋ ํด๋น ํ์ผ์ ๋ชจ๋๋ก ์ฒ๋ฆฌํ๊ณ , Vite๊ฐ ์ ๊ณตํ๋ ํ์ผ์ ์ ์์ ์ผ๋ก ์คํ.
new URL('/src/utils/chatWorker.ts', import.meta.url)์ ๋ค์ ๋จ๊ณ๋ฅผ ๊ฑฐ์นฉ๋๋ค:
- Vite๋
import.meta.url์ ํตํด ํ์ฌ ๋ชจ๋์ URL์ ๊ณ์ฐ. -
/src/utils/chatWorker.ts๊ฒฝ๋ก๋ฅผ ํ์ฌ ๋ชจ๋์ URL์ ๊ธฐ์ค์ผ๋ก ํด์. - ์์ปค ํ์ผ์
http://localhost:3000/src/utils/chatWorker.ts์ฒ๋ผ ๋ธ๋ผ์ฐ์ ์์ ์ ๊ทผ ๊ฐ๋ฅํ URL๋ก ๋ณํ. - ๋ธ๋ผ์ฐ์ ๊ฐ ํด๋น URL๋ก ์์ฒญ์ ๋ณด๋.
- Vite ๊ฐ๋ฐ ์๋ฒ๊ฐ ํด๋น ํ์ผ์ ๋์ ์ผ๋ก ์ฒ๋ฆฌํ์ฌ ๋ฐํ.
-
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;
์๋ ํด๋ผ์ด์ธํธ ํญ์ 2๊ฐ ๋์ ์๋์ ์๋ฒ ๋ก๊ทธ์ด๋ค.
์ฒ์ ํญ์ด ์ด๋ ธ์ ๋ shared worker๋ ๊ณต์ ๋ ์์ผ ํ๋๋ฅผ ์์ฑํ๋ค (id: un19~)
๊ทธ๋ฆฌ๊ณ ํญ์ผ ์ด๋ ธ์ ๋ ํด๋ผ์ด์ธํธ์์ โHello from Reactโ๋ฅผ shared worker์๊ฒ postMessage๋ฅผ ํ๊ณ worker๋ ๋ฐ์ ๋ฉ์ธ์ง๋ฅผ ์์ ์ socket์ ํตํด ์๋ฒ๋ก ์ ์กํ๋ค.
๋ค๋ฅธ ํญ์ ์ด๋ ธ์ ๋๋ ์ด๋ฏธ ์์ผ์ด ์๊ธฐ ๋๋ฌธ์ ์๋ก ์์ฑ์ด ์ด๋ค์ง์ง ์๊ณ ์ด๋ฏธ ์กด์ฌํ๋ ์์ผ์ผ๋ก ๋๋ค์ ์๋ฒ์ ๋ฉ์ธ์ง๋ฅผ ๋ณด๋ธ ๊ฑธ ํ์ธํ ์ ์๋ค.
ํด๋น ๊ณผ์ ์ ์ข๋ ํ์คํ๊ฒ ๋ณด๊ณ ์ port๊ฐ ์ฐ๊ฒฐ๋ ๋๋ง๋ค ์นด์ดํ
์ ํ๊ณ ๋ก๊ทธ๋ฅผ ์ฐ์ด๋ณด์๋ค.
์๋ก์ด ํญ์ ์ด๊ฑฐ๋ ์๋ก๊ณ ์นจ์ ํ ๋๋ง๋ค ์๋ก์ด ์์ผ์ด ์์ฑ๋๋ ๊ฒ์ด ์๋ ํ๋์ ์์ผ์ ์ฌ๋ฌ ํฌํธ(ํญ)์์ ๊ณต์ ํ๊ณ ์๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
๋ง์ฝ ํฌํธ(ํญ)์ ์ฌ์ฉํ์ง ์๊ฒ๋๋ค๋ฉด ํฌํธ์ ๋ํ ๊ณต๊ฐ์ ์ ๊ฑฐํ๋ ๋ฐฉ์์ ๊ฐ๋น์ง ์ฝ๋ ํฐ๋ฅผ ์ด์ฉํ๋ค๊ณ ํ๋ค. ํ์ ์์๋ณด์..
- ๐ ์น ์์ผ์ ์ค์๊ฐ ์๋ฐฉํฅ ํต์ (feat. WS vs Socket.io)
- ๐คธโโ๏ธ ๋น์ ์ด ์ปดํฌ๋ํธ๋ก ๋ ๋๋ง ์ต์ ํ ํ๊ธฐ
- ๐ทโโ๏ธ Shared Worker๋ก ํด๋ผ์ด์ธํธ์ ์์ผ ํต์ ๊ฐ์ ํ๊ธฐ
- ๐จโ๐ฉโ๐งโ๐ฆ ๋ค์ค ํญ์์ ํ๋์ ์์ผ์ ๊ณต์ ํ ์ ์์๊น?
- ๐ [Socket.io] ํด๋ผ์ด์ธํธ์ ์ค์๊ฐ ์ฑํ ๊ตฌํ๊ธฐ
- ๐ฌ ์๋ฒ๋ฅผ docker swarm ์ผ๋ก ๊ด๋ฆฌํด๋ณด์
- ๐ฌ ์ปจํ ์ด๋๋ผ๋ฆฌ env ๊ณต์ ํ๊ธฐ
- ํ์ฅ์ฑ์ ๊ณ ๋ คํ ์๋ฒ ์ค๊ณ
- ncp ์๋ฒ ์ ํ
- ์ฑํ ์๋ฒ์ Redis ๋ฅผ ์ด ์ด์
- โ NestJS๋ฅผ ํตํ ์ผ๊ด์ ์ธ ์์คํ ์ค๊ณ
โ๏ธ ์ธ๋ถ์ ์ฌ์ฉ์๊ฐ Object Storage์ ์ ๊ทผํ์ง ๋ชปํ๋ ๊ถํ ์ ์ด- ๐ฆข nestjs์์ swagger ์ฌ์ฉํด๋ณด๊ธฐ
- ๐ NestJS Nginx Request Data Size ๋ฌธ์
- ๐ ๋ค์๋ณด๊ธฐ๋ฅผ ์ํ NodeโMediaโServer, FFMpeg ๋ถ์
- ๐ฆ ํจํค์ง ๋งค๋์ ๋ฐ ๋ชจ๋ ธ๋ ํฌ ์ ํ๊ธฐ
- ๐ฐ ์ปค์คํ ESLint ๋ง๋ค๊ธฐ
- ๐คบ ์ปค์คํ react ์ค๋ํซ ๋ง๋ค๊ธฐ
- ๐ธ ๋ฐ์ํ ๋น๋์ค ํ๋ ์ด์ด ๊ตฌํ: ํจ๋ฉ ํ ๊ธฐ๋ฒ
- ๋ฆฌ์กํธ ํ ํผ ๋ฅ๋ค์ด๋ธ