์‚ฌ์šฉ์ž ๋„๊ตฌ

์‚ฌ์ดํŠธ ๋„๊ตฌ


wiki:it:dream_of_enc:metaverse:nodejs

์ฐจ์ด

๋ฌธ์„œ์˜ ์„ ํƒํ•œ ๋‘ ํŒ ์‚ฌ์ด์˜ ์ฐจ์ด๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

์ฐจ์ด ๋ณด๊ธฐ๋กœ ๋งํฌ

๋‹ค์Œ ํŒ
์ด์ „ ํŒ
wiki:it:dream_of_enc:metaverse:nodejs [2025/07/28 05:57] โ€“ ๋งŒ๋“ฆ - ๋ฐ”๊นฅ ํŽธ์ง‘ 127.0.0.1wiki:it:dream_of_enc:metaverse:nodejs [2025/07/30 06:43] (ํ˜„์žฌ) โ€“ ๋ฐ”๊นฅ ํŽธ์ง‘ 127.0.0.1
์ค„ 1: ์ค„ 1:
 ====== ๐ŸŸข Node.js ๋ฐฑ์—”๋“œ ์„ค์ • ====== ====== ๐ŸŸข Node.js ๋ฐฑ์—”๋“œ ์„ค์ • ======
  
-Phaser Baduk Metaverse ํ”„๋กœ์ ํŠธ์˜ Node.js ๋ฐฑ์—”๋“œ ์„ค์ •๊ณผ ๊ตฌ์„ฑ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.+Phaser Baduk Metaverse ํ”„๋กœ์ ํŠธ์˜ ''Node.js'' ๋ฐฑ์—”๋“œ ์„ค์ •๊ณผ ๊ตฌ์„ฑ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.
  
-===== ๐Ÿ“‹ ๊ฐœ์š” =====+----ย 
 +===== 1. Node.js๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”=====
  
-์ด ํ”„๋กœ์ ํŠธ๋Š” Node.js๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง๊ณผ ์‹ค์‹œ๊ฐ„ ํ†ต์‹ ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.+''Node.js''๋Š” ''JavaScript''๋ฅผ ์„œ๋ฒ„์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ์ž…๋‹ˆ๋‹ค. ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ๋งŒ ์‹คํ–‰๋˜๋˜ ''JavaScript''๋ฅผ ์„œ๋ฒ„์—์„œ๋„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.
  
-===== ๐Ÿ—๏ธ ์„œ๋ฒ„ ๊ตฌ์กฐ =====+**์ฃผ์š” ํŠน์ง•:**ย 
 +  * ''JavaScript''๋กœ ์„œ๋ฒ„๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.ย 
 +  * ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ์— ๊ฐ•์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.ย 
 +  * ''npm''์„ ํ†ตํ•ด ๋‹ค์–‘ํ•œ ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.ย 
 +  * ๋น ๋ฅธ ๊ฐœ๋ฐœ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  
-**๋ฉ”์ธ ์„œ๋ฒ„ ํŒŒ์ผ (server.js):**ย +----ย 
-<code javascript>+===== 2. ํ”„๋กœ์ ํŠธ ๊ฐœ์š” =====ย 
 +ย 
 +์ด ํ”„๋กœ์ ํŠธ๋Š” ''Node.js''๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋ฉฐ, ์›น ํŽ˜์ด์ง€๋ฅผ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋งํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ์™€์˜ ์‹ค์‹œ๊ฐ„ ํ†ต์‹  ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +**์ฃผ์š” ๊ธฐ์ˆ  ์Šคํƒ:**ย 
 +  * **''Express.js''** - ์›น ํ”„๋ ˆ์ž„์›Œํฌย 
 +  * **''Socket.IO''** - ์‹ค์‹œ๊ฐ„ ํ†ต์‹  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌย 
 +  * **''PM2''** - ํ”„๋กœ์„ธ์Šค ๊ด€๋ฆฌ ๋„๊ตฌย 
 +ย 
 +----ย 
 +===== 3. ์„œ๋ฒ„ ๊ตฌ์กฐ ๋ฐ ์ฃผ์š” ํŒŒ์ผ =====ย 
 +ย 
 +Phaser Baduk Metaverse ํ”„๋กœ์ ํŠธ์˜ ํ•ต์‹ฌ ์„œ๋ฒ„ ํŒŒ์ผ์ธ ''server.js''์˜ ๊ตฌ์กฐ์™€ ๊ฐ ๋ถ€๋ถ„์˜ ์—ญํ• ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +==== 1) ์ดˆ๊ธฐ ์„ค์ • ๋ฐ ๋ชจ๋“ˆ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ====ย 
 +ย 
 +์„œ๋ฒ„ ๊ตฌ๋™์— ํ•„์š”ํ•œ ๋ชจ๋“ˆ๋“ค์„ ๋ถˆ๋Ÿฌ์˜ค๊ณ , ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +<file javascript>ย 
 +const express = require('express'); // ์›น ์„œ๋ฒ„ ํ”„๋ ˆ์ž„์›Œํฌย 
 +const http = require('http');     // HTTP ์„œ๋ฒ„ ๋ชจ๋“ˆย 
 +const socketIo = require('socket.io'); // ์‹ค์‹œ๊ฐ„ ์›น ์†Œ์ผ“ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌย 
 +const path = require('path');     // ํŒŒ์ผ ๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ์œ ํ‹ธ๋ฆฌํ‹ฐย 
 +</file>ย 
 +ย 
 +**๊ฐ ๋ชจ๋“ˆ์˜ ์—ญํ• :**ย 
 +  * ''express'' - ์›น ์„œ๋ฒ„๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ํ”„๋ ˆ์ž„์›Œํฌย 
 +  * ''http'' - ''HTTP'' ์„œ๋ฒ„๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ธฐ๋ณธ ๋ชจ๋“ˆย 
 +  * ''socket.io'' - ์‹ค์‹œ๊ฐ„ ์–‘๋ฐฉํ–ฅ ํ†ต์‹ ์„ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌย 
 +  * ''path'' - ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š” ์œ ํ‹ธ๋ฆฌํ‹ฐย 
 +ย 
 +==== 2) ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ====ย 
 +ย 
 +<file javascript>ย 
 +const app = express(); // Express ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ƒ์„ฑย 
 +const server = http.createServer(app); // HTTP ์„œ๋ฒ„ ์ƒ์„ฑ (Express ์•ฑ์„ ๊ธฐ๋ฐ˜์œผ๋กœ)ย 
 +const io = socketIo(server); // Socket.IO ์„œ๋ฒ„ ์ƒ์„ฑ (HTTP ์„œ๋ฒ„์— ์—ฐ๊ฒฐ)ย 
 +</file>ย 
 +ย 
 +**์„ค๋ช…:**ย 
 +  * ''app'' - ''Express'' ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐ์ฒดย 
 +  * ''server'' - ''HTTP'' ์„œ๋ฒ„ ๊ฐ์ฒด (''Express'' ์•ฑ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒ์„ฑ)ย 
 +  * ''io'' - ''Socket.IO'' ์„œ๋ฒ„ ๊ฐ์ฒด (''HTTP'' ์„œ๋ฒ„์— ์—ฐ๊ฒฐ)ย 
 +ย 
 +==== 3) ์ •์  ํŒŒ์ผ ์„œ๋น™ ๋ฐ ๋ผ์šฐํŒ… ====ย 
 +ย 
 +ํด๋ผ์ด์–ธํŠธ(ํ”„๋ก ํŠธ์—”๋“œ)์— ์ œ๊ณต๋  ์ •์  ํŒŒ์ผ(''HTML'', ''CSS'', ''JS'', ์ด๋ฏธ์ง€ ๋“ฑ)์„ ์„ค์ •ํ•˜๊ณ , ๊ธฐ๋ณธ ๊ฒฝ๋กœ์— ๋Œ€ํ•œ ๋ผ์šฐํŠธ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +<file javascript>ย 
 +// 'public' ๋””๋ ‰ํ† ๋ฆฌ์— ์žˆ๋Š” ์ •์  ํŒŒ์ผ๋“ค์„ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ œ๊ณตย 
 +app.use(express.static(path.join(dirname, 'public')));ย 
 +ย 
 +// ๋ฃจํŠธ ๊ฒฝ๋กœ('/')๋กœ ์ ‘๊ทผ ์‹œ 'public' ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด์˜ 'index.html' ํŒŒ์ผ ์ „์†กย 
 +app.get('/', (req, res) => {ย 
 +    res.sendFile(path.join(dirname, 'public', 'index.html'));ย 
 +});ย 
 +</file>ย 
 +ย 
 +**์„ค๋ช…:**ย 
 +  * ''express.static()'' - ์ •์  ํŒŒ์ผ์„ ์›น์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.ย 
 +  * ''path.join(dirname, 'public')'' - ํ˜„์žฌ ๋””๋ ‰ํ† ๋ฆฌ์˜ ''public'' ํด๋” ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค.ย 
 +  * ''app.get('/')'' - ๋ฃจํŠธ ๊ฒฝ๋กœ๋กœ ์ ‘๊ทผํ–ˆ์„ ๋•Œ ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.ย 
 +ย 
 +==== 4) Socket.IO ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ====ย 
 +ย 
 +ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„์˜ ์‹ค์‹œ๊ฐ„ ํ†ต์‹ ์„ ๋‹ด๋‹นํ•˜๋Š” ''Socket.IO'' ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +<file javascript>ย 
 +// Socket.IO ์—ฐ๊ฒฐ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌย 
 +io.on('connection', (socket) => {ย 
 +    // ์ƒˆ๋กœ์šด ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์—ฐ๊ฒฐ๋  ๋•Œ๋งˆ๋‹ค ์‹คํ–‰ย 
 +    console.log('์ƒˆ๋กœ์šด ํด๋ผ์ด์–ธํŠธ ์—ฐ๊ฒฐ:', socket.id);ย 
 +    ย 
 +    // 'join-game' ์ด๋ฒคํŠธ ์ˆ˜์‹  ์‹œ ํŠน์ • ๊ฒŒ์ž„๋ฐฉ์— ํด๋ผ์ด์–ธํŠธ ์กฐ์ธย 
 +    socket.on('join-game', (gameId) => {ย 
 +        socket.join(gameId); // ํ•ด๋‹น gameId๋ฅผ ๊ฐ€์ง„ ๋ฐฉ์— ์†Œ์ผ“์„ ์ถ”๊ฐ€ย 
 +        console.log(`ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ๊ฒŒ์ž„ ${gameId}์— ์ฐธ๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.`);ย 
 +    });ย 
 +    ย 
 +    // ํด๋ผ์ด์–ธํŠธ ์—ฐ๊ฒฐ ํ•ด์ œ ์‹œ ์‹คํ–‰ย 
 +    socket.on('disconnect', () => {ย 
 +        console.log('ํด๋ผ์ด์–ธํŠธ ์—ฐ๊ฒฐ ํ•ด์ œ:', socket.id);ย 
 +    });ย 
 +});ย 
 +</file>ย 
 +ย 
 +**์„ค๋ช…:**ย 
 +  * ''io.on('connection')'' - ์ƒˆ๋กœ์šด ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์—ฐ๊ฒฐ๋  ๋•Œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.ย 
 +  * ''socket.on('join-game')'' - ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ฒŒ์ž„ ์ฐธ๊ฐ€ ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.ย 
 +  * ''socket.join(gameId)'' - ํŠน์ • ๊ฒŒ์ž„๋ฐฉ์— ์†Œ์ผ“์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.ย 
 +  * ''socket.on('disconnect')'' - ํด๋ผ์ด์–ธํŠธ ์—ฐ๊ฒฐ์ด ๋Š์–ด์งˆ ๋•Œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +==== 5) ์„œ๋ฒ„ ํฌํŠธ ์„ค์ • ๋ฐ ์‹คํ–‰ ====ย 
 +ย 
 +ํ™˜๊ฒฝ ๋ณ€์ˆ˜์—์„œ ํฌํŠธ ๋ฒˆํ˜ธ๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ๊ธฐ๋ณธ๊ฐ’(3000)์„ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„๋ฅผ ์ง€์ •๋œ ํฌํŠธ์—์„œ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +<file javascript>ย 
 +// ํ™˜๊ฒฝ ๋ณ€์ˆ˜์—์„œ PORT๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ๊ธฐ๋ณธ๊ฐ’ 3000 ์‚ฌ์šฉย 
 +const PORT = process.env.PORT || 3000;ย 
 +ย 
 +// ์„œ๋ฒ„๋ฅผ ์ง€์ •๋œ ํฌํŠธ์—์„œ ์‹คํ–‰ํ•˜๊ณ , ์„ฑ๊ณต ์‹œ ์ฝ˜์†”์— ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅย 
 +server.listen(PORT, () => {ย 
 +    console.log(`์„œ๋ฒ„๊ฐ€ ํฌํŠธ ${PORT}์—์„œ ์‹คํ–‰ ์ค‘์ž…๋‹ˆ๋‹ค.`);ย 
 +    console.log(`http://localhost:${PORT}์—์„œ ์ ‘์†ํ•˜์„ธ์š”.`);ย 
 +});ย 
 +</file>ย 
 +ย 
 +**์„ค๋ช…:**ย 
 +  * ''process.env.PORT'' - ํ™˜๊ฒฝ ๋ณ€์ˆ˜์—์„œ ํฌํŠธ ๋ฒˆํ˜ธ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.ย 
 +  * ''|| 3000'' - ํ™˜๊ฒฝ ๋ณ€์ˆ˜๊ฐ€ ์—†์œผ๋ฉด ๊ธฐ๋ณธ๊ฐ’ 3000์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.ย 
 +  * ''server.listen()'' - ์„œ๋ฒ„๋ฅผ ์ง€์ •๋œ ํฌํŠธ์—์„œ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.ย 
 +  * ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋Š” ์„œ๋ฒ„ ์‹œ์ž‘ ์„ฑ๊ณต ์‹œ ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.ย 
 +ย 
 +----ย 
 +===== 4. ์˜์กด์„ฑ ๊ด€๋ฆฌ (package.json) =====ย 
 +ย 
 +ํ”„๋กœ์ ํŠธ์— ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฐ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ •์˜ํ•˜๋Š” ''package.json'' ํŒŒ์ผ์˜ ์ฃผ์š” ๋‚ด์šฉ์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +==== 1) ํ”„๋กœ์ ํŠธ ์ •๋ณด ====ย 
 +ย 
 +^ ํ‚ค ^ ์„ค๋ช… ^ย 
 +| name | ํ”„๋กœ์ ํŠธ ์ด๋ฆ„ |ย 
 +| version | ํ”„๋กœ์ ํŠธ ๋ฒ„์ „ |ย 
 +| description | ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ๊ฐ„๋žตํ•œ ์„ค๋ช… |ย 
 +| main | ํ”„๋กœ์ ํŠธ์˜ ์ง„์ž…์  ํŒŒ์ผ (์—ฌ๊ธฐ์„œ๋Š” ''server.js''|ย 
 +ย 
 +==== 2) ์Šคํฌ๋ฆฝํŠธ ====ย 
 +ย 
 +์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๋ช…๋ น์–ด๋ฅผ ๋‹จ์ถ•ํ•˜์—ฌ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +^ ์Šคํฌ๋ฆฝํŠธ ^ ์„ค๋ช… ^ ๋ช…๋ น์–ด ^ย 
 +| start | ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ ์„œ๋ฒ„๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. | ''node server.js'' |ย 
 +| dev | ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ ''nodemon''์„ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ ๋ณ€๊ฒฝ ์‹œ ์ž๋™ ์žฌ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. | ''nodemon server.js'' |ย 
 +| pm2 | ''PM2''๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. (ํ”„๋กœ์„ธ์Šค ๊ด€๋ฆฌ์šฉ) | ''pm2 start server.js'' |ย 
 +ย 
 +==== 3) ์˜์กด์„ฑ ๋ชฉ๋ก ====ย 
 +ย 
 +^ ์˜์กด์„ฑ ^ ๋ฒ„์ „ ^ ์„ค๋ช… ^ย 
 +| express | 4.18.2 | Node.js ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ”„๋ ˆ์ž„์›Œํฌ |ย 
 +| socket.io | 4.7.2 | ์‹ค์‹œ๊ฐ„ ์–‘๋ฐฉํ–ฅ ์›น ์†Œ์ผ“ ํ†ต์‹  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ |ย 
 +| cors | 2.8.5 | ๊ต์ฐจ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ  (CORS) ๋ฏธ๋“ค์›จ์–ด |ย 
 +| helmet | 7.0.0 | ๋ณด์•ˆ ํ—ค๋” ์„ค์ • ๋ฏธ๋“ค์›จ์–ด |ย 
 +| compression | 1.7.4 | ์‘๋‹ต ์••์ถ• ๋ฏธ๋“ค์›จ์–ด |ย 
 +| express-rate-limit | 6.7.0 | ์š”์ฒญ ์ œํ•œ ๋ฏธ๋“ค์›จ์–ด |ย 
 +ย 
 +==== 4) ๊ฐœ๋ฐœ ์˜์กด์„ฑ ๋ชฉ๋ก ====ย 
 +ย 
 +^ ์˜์กด์„ฑ ^ ๋ฒ„์ „ ^ ์„ค๋ช… ^ย 
 +| nodemon | 2.0.22 | ๊ฐœ๋ฐœ ์‹œ ์ฝ”๋“œ ๋ณ€๊ฒฝ ๊ฐ์ง€ํ•˜์—ฌ ์„œ๋ฒ„ ์ž๋™ ์žฌ์‹œ์ž‘ |ย 
 +| jest | 29.5.0 | JavaScript ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ |ย 
 +| supertest | 6.3.3 | HTTP ํ…Œ์ŠคํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ |ย 
 +ย 
 +----ย 
 +===== 5. ํ™˜๊ฒฝ ์„ค์ • =====ย 
 +ย 
 +==== 1) ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ • ====ย 
 +ย 
 +ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— ''.env'' ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜์—ฌ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค:ย 
 +ย 
 +<file bash>ย 
 +# ์„œ๋ฒ„ ํฌํŠธ ์„ค์ •ย 
 +PORT=3000ย 
 +ย 
 +# ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ์ •๋ณดย 
 +MONGODB_URI=mongodb://localhost:27017/baduk_metaverseย 
 +ย 
 +# JWT ์‹œํฌ๋ฆฟ ํ‚คย 
 +JWT_SECRET=your-secret-key-hereย 
 +ย 
 +# ํ™˜๊ฒฝ ์„ค์ •ย 
 +NODE_ENV=developmentย 
 +</file>ย 
 +ย 
 +**์ฃผ์š” ํ™˜๊ฒฝ ๋ณ€์ˆ˜:**ย 
 +  * ''PORT'' - ์„œ๋ฒ„๊ฐ€ ์‹คํ–‰๋  ํฌํŠธ ๋ฒˆํ˜ธย 
 +  * ''MONGODB_URI'' - ''MongoDB'' ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ๋ฌธ์ž์—ดย 
 +  * ''JWT_SECRET'' - ''JWT'' ํ† ํฐ ์•”ํ˜ธํ™”์— ์‚ฌ์šฉํ•  ์‹œํฌ๋ฆฟ ํ‚คย 
 +  * ''NODE_ENV'' - ํ˜„์žฌ ํ™˜๊ฒฝ (''development''/''production'')ย 
 +ย 
 +==== 2) ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์‚ฌ์šฉ๋ฒ• ====ย 
 +ย 
 +<file javascript>ย 
 +// dotenv ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ .env ํŒŒ์ผ ๋กœ๋“œย 
 +require('dotenv').config();ย 
 +ย 
 +// ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์‚ฌ์šฉย 
 +const PORT = process.env.PORT || 3000;ย 
 +const MONGODB_URI = process.env.MONGODB_URI;ย 
 +const JWT_SECRET = process.env.JWT_SECRET;ย 
 +</file>ย 
 +ย 
 +**์„ค๋ช…:**ย 
 +  * ''require('dotenv').config()'' - ''.env'' ํŒŒ์ผ์„ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.ย 
 +  * ''process.env.๋ณ€์ˆ˜๋ช…'' - ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.ย 
 +  * ''|| ๊ธฐ๋ณธ๊ฐ’'' - ํ™˜๊ฒฝ ๋ณ€์ˆ˜๊ฐ€ ์—†์„ ๋•Œ ๊ธฐ๋ณธ๊ฐ’์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +----ย 
 +===== 6. ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ =====ย 
 +ย 
 +**๊ถŒ์žฅํ•˜๋Š” ํ”„๋กœ์ ํŠธ ํด๋” ๊ตฌ์กฐ:**ย 
 +ย 
 +<file>ย 
 +baduk-metaverse/ย 
 +โ”œโ”€โ”€ server.js              # ๋ฉ”์ธ ์„œ๋ฒ„ ํŒŒ์ผย 
 +โ”œโ”€โ”€ package.json           # ํ”„๋กœ์ ํŠธ ์„ค์ • ํŒŒ์ผย 
 +โ”œโ”€โ”€ .env                   # ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ํŒŒ์ผย 
 +โ”œโ”€โ”€ .gitignore            # Git ๋ฌด์‹œ ํŒŒ์ผ ๋ชฉ๋กย 
 +โ”œโ”€โ”€ public/               # ์ •์  ํŒŒ์ผ ํด๋”ย 
 +โ”‚   โ”œโ”€โ”€ index.html        # ๋ฉ”์ธ HTML ํŒŒ์ผย 
 +โ”‚   โ”œโ”€โ”€ css/              # CSS ํŒŒ์ผ๋“คย 
 +โ”‚   โ”œโ”€โ”€ js/               # ํด๋ผ์ด์–ธํŠธ JavaScript ํŒŒ์ผ๋“คย 
 +โ”‚   โ””โ”€โ”€ images/           # ์ด๋ฏธ์ง€ ํŒŒ์ผ๋“คย 
 +โ”œโ”€โ”€ routes/               # ๋ผ์šฐํŠธ ํŒŒ์ผ๋“คย 
 +โ”‚   โ”œโ”€โ”€ games.js          # ๊ฒŒ์ž„ ๊ด€๋ จ ๋ผ์šฐํŠธย 
 +โ”‚   โ”œโ”€โ”€ users.js          # ์‚ฌ์šฉ์ž ๊ด€๋ จ ๋ผ์šฐํŠธย 
 +โ”‚   โ””โ”€โ”€ statistics.js     # ํ†ต๊ณ„ ๊ด€๋ จ ๋ผ์šฐํŠธย 
 +โ”œโ”€โ”€ controllers/          # ์ปจํŠธ๋กค๋Ÿฌ ํŒŒ์ผ๋“คย 
 +โ”‚   โ”œโ”€โ”€ BadukGameController.jsย 
 +โ”‚   โ”œโ”€โ”€ UserController.jsย 
 +โ”‚   โ””โ”€โ”€ StatisticsController.jsย 
 +โ”œโ”€โ”€ models/               # ๋ฐ์ดํ„ฐ ๋ชจ๋ธ ํŒŒ์ผ๋“คย 
 +โ”‚   โ”œโ”€โ”€ BadukGame.jsย 
 +โ”‚   โ”œโ”€โ”€ User.jsย 
 +โ”‚   โ””โ”€โ”€ BadukGameState.jsย 
 +โ”œโ”€โ”€ middleware/           # ๋ฏธ๋“ค์›จ์–ด ํŒŒ์ผ๋“คย 
 +โ”‚   โ”œโ”€โ”€ auth.js           # ์ธ์ฆ ๋ฏธ๋“ค์›จ์–ดย 
 +โ”‚   โ””โ”€โ”€ errorHandler.js   # ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฏธ๋“ค์›จ์–ดย 
 +โ”œโ”€โ”€ utils/                # ์œ ํ‹ธ๋ฆฌํ‹ฐ ํŒŒ์ผ๋“คย 
 +โ”‚   โ”œโ”€โ”€ BadukMoveValidator.jsย 
 +โ”‚   โ””โ”€โ”€ helpers.jsย 
 +โ””โ”€โ”€ tests/                # ํ…Œ์ŠคํŠธ ํŒŒ์ผ๋“คย 
 +    โ”œโ”€โ”€ server.test.jsย 
 +    โ””โ”€โ”€ game.test.jsย 
 +</file>ย 
 +ย 
 +**๊ฐ ํด๋”์˜ ์—ญํ• :**ย 
 +  * ''public/'' - ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ œ๊ณตํ•  ํŒŒ์ผ๋“คย 
 +  * ''routes/'' - ''URL'' ๊ฒฝ๋กœ๋ณ„ ์ฒ˜๋ฆฌ ๋กœ์งย 
 +  * ''controllers/'' - ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ฒ˜๋ฆฌย 
 +  * ''models/'' - ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ ์ •์˜ย 
 +  * ''middleware/'' - ์š”์ฒญ ์ฒ˜๋ฆฌ ์ค‘๊ฐ„ ๋‹จ๊ณ„ย 
 +  * ''utils/'' - ๊ณตํ†ต ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜๋“คย 
 +  * ''tests/'' - ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋“คย 
 +ย 
 +----ย 
 +===== 7. ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ • =====ย 
 +ย 
 +==== 1) Node.js ์„ค์น˜ ====ย 
 +ย 
 +**Windows์—์„œ Node.js ์„ค์น˜:**ย 
 +  * ''Node.js'' ๊ณต์‹ ์›น์‚ฌ์ดํŠธ (''https://nodejs.org'') ๋ฐฉ๋ฌธย 
 +  * ''LTS'' ๋ฒ„์ „ ๋‹ค์šด๋กœ๋“œ ๋ฐ ์„ค์น˜ย 
 +  * ์„ค์น˜ ์™„๋ฃŒ ํ›„ ํ„ฐ๋ฏธ๋„์—์„œ ํ™•์ธ:ย 
 +<file bash>ย 
 +node --versionย 
 +npm --versionย 
 +</file>ย 
 +ย 
 +==== 2) ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐํ™” ====ย 
 +ย 
 +<file bash>ย 
 +# ์ƒˆ ํด๋” ์ƒ์„ฑ ๋ฐ ์ด๋™ย 
 +mkdir baduk-metaverseย 
 +cd baduk-metaverseย 
 +ย 
 +# npm ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐํ™”ย 
 +npm init -yย 
 +ย 
 +# ํ•„์š”ํ•œ ํŒจํ‚ค์ง€ ์„ค์น˜ย 
 +npm install express socket.io cors helmet compression express-rate-limitย 
 +ย 
 +# ๊ฐœ๋ฐœ์šฉ ํŒจํ‚ค์ง€ ์„ค์น˜ย 
 +npm install --save-dev nodemonย 
 +</file>ย 
 +ย 
 +==== 3) ๊ธฐ๋ณธ ์„œ๋ฒ„ ํŒŒ์ผ ์ƒ์„ฑ ====ย 
 +ย 
 +''server.js'' ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ  ๊ธฐ๋ณธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค:ย 
 +ย 
 +<file javascript>
 const express = require('express'); const express = require('express');
 const http = require('http'); const http = require('http');
์ค„ 21: ์ค„ 305:
  
 // ์ •์  ํŒŒ์ผ ์„œ๋น™ // ์ •์  ํŒŒ์ผ ์„œ๋น™
-app.use(express.static(path.join(__dirname, 'public')));+app.use(express.static(path.join(dirname, 'public')));
  
-// ๋ผ์šฐํŠธ ์„ค์ •+// ๊ธฐ๋ณธ ๋ผ์šฐํŠธ
 app.get('/', (req, res) => { app.get('/', (req, res) => {
-    res.sendFile(path.join(__dirname, 'public', 'index.html'));+    res.sendFile(path.join(dirname, 'public', 'index.html'));
 }); });
  
-// Socket.IO ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ+// Socket.IO ์—ฐ๊ฒฐ ์ฒ˜๋ฆฌ
 io.on('connection', (socket) => { io.on('connection', (socket) => {
     console.log('์ƒˆ๋กœ์šด ํด๋ผ์ด์–ธํŠธ ์—ฐ๊ฒฐ:', socket.id);     console.log('์ƒˆ๋กœ์šด ํด๋ผ์ด์–ธํŠธ ์—ฐ๊ฒฐ:', socket.id);
-     
-    socket.on('join-game', (gameId) => { 
-        socket.join(gameId); 
-        console.log(`ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ๊ฒŒ์ž„ ${gameId}์— ์ฐธ๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.`); 
-    }); 
          
     socket.on('disconnect', () => {     socket.on('disconnect', () => {
์ค„ 42: ์ค„ 321:
 }); });
  
 +// ์„œ๋ฒ„ ์‹œ์ž‘
 const PORT = process.env.PORT || 3000; const PORT = process.env.PORT || 3000;
 server.listen(PORT, () => { server.listen(PORT, () => {
     console.log(`์„œ๋ฒ„๊ฐ€ ํฌํŠธ ${PORT}์—์„œ ์‹คํ–‰ ์ค‘์ž…๋‹ˆ๋‹ค.`);     console.log(`์„œ๋ฒ„๊ฐ€ ํฌํŠธ ${PORT}์—์„œ ์‹คํ–‰ ์ค‘์ž…๋‹ˆ๋‹ค.`);
 }); });
-</code>+</file>
  
-===== ๐Ÿ“ฆ ์˜์กด์„ฑ ๊ด€๋ฆฌ =====+==== 4) package.json ์Šคํฌ๋ฆฝํŠธ ์„ค์ • ====
  
-**package.json ์ฃผ์š” ์˜์กด์„ฑ:**ย +<file json>
-<code json>+
 { {
-  "name": "phaser-baduk-metaverse",+  "name": "baduk-metaverse",
   "version": "1.0.0",   "version": "1.0.0",
-  "description": "Phaser.js ๊ธฐ๋ฐ˜ ๋ฐ”๋‘‘ ๋ฉ”ํƒ€๋ฒ„์Šค ๊ฒŒ์ž„",+  "description": "Phaser Baduk Metaverse ํ”„๋กœ์ ํŠธ",
   "main": "server.js",   "main": "server.js",
   "scripts": {   "scripts": {
     "start": "node server.js",     "start": "node server.js",
     "dev": "nodemon server.js",     "dev": "nodemon server.js",
-    "pm2": "pm2 start server.js"+    "test": "jest"
   },   },
   "dependencies": {   "dependencies": {
     "express": "^4.18.2",     "express": "^4.18.2",
     "socket.io": "^4.7.2",     "socket.io": "^4.7.2",
-    "cors": "^2.8.5"+    "cors": "^2.8.5",ย 
 +    "helmet": "^7.0.0",ย 
 +    "compression": "^1.7.4",ย 
 +    "express-rate-limit": "^6.7.0"
   },   },
   "devDependencies": {   "devDependencies": {
-    "nodemon": "^3.0.1"+    "nodemon": "^2.0.22",ย 
 +    "jest": "^29.5.0"
   }   }
 } }
-</code>+</file>
  
-===== ๐Ÿ”ง ํ™˜๊ฒฝ ์„ค์ • =====+----ย 
 +===== 8. ์„œ๋ฒ„ ์‹คํ–‰ ๋ฐ ํ…Œ์ŠคํŠธ =====
  
-**ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ •:**ย +==== 1) ๊ฐœ๋ฐœ ๋ชจ๋“œ๋กœ ์„œ๋ฒ„ ์‹คํ–‰ ====
-<code bash>ย +
-# .env ํŒŒ์ผย +
-NODE_ENV=developmentย +
-PORT=3000ย +
-DB_PATH=./db.jsonย +
-</code>+
  
-**๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์‹คํ–‰:**ย +<file bash>
-<code bash>ย +
-# ๊ฐœ๋ฐœ ๋ชจ๋“œ (nodemon ์‚ฌ์šฉ)+
 npm run dev npm run dev
 +</file>
  
-ํ”„๋กœ๋•์…˜ ๋ชจ๋“œ+**์„ค๋ช…:**ย 
 +  * ''nodemon''์„ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.ย 
 +  * ์ฝ”๋“œ ๋ณ€๊ฒฝ ์‹œ ์ž๋™์œผ๋กœ ์„œ๋ฒ„๊ฐ€ ์žฌ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค.ย 
 +  * ๊ฐœ๋ฐœ ์ค‘์— ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +==== 2) ํ”„๋กœ๋•์…˜ ๋ชจ๋“œ๋กœ ์„œ๋ฒ„ ์‹คํ–‰ ====ย 
 +ย 
 +<file bash>
 npm start npm start
-</code>+</file>
  
-===== ๐Ÿ—„๏ธ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ =====+**์„ค๋ช…:**ย 
 +  * ''node''๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.ย 
 +  * ์ฝ”๋“œ ๋ณ€๊ฒฝ ์‹œ ์ˆ˜๋™์œผ๋กœ ์„œ๋ฒ„๋ฅผ ์žฌ์‹œ์ž‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.ย 
 +  * ์‹ค์ œ ์„œ๋น„์Šค ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  
-**๊ฒŒ์ž„ ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ (db.json):**ย +==== 3์„œ๋ฒ„ ํ…Œ์ŠคํŠธ ====
-<code json>ย +
-{ย +
-  "games": {},ย +
-  "users": {},ย +
-  "rooms": {},ย +
-  "statistics": {ย +
-    "totalGames": 0,ย +
-    "activePlayers": 0ย +
-  }ย +
-}ย +
-</code>+
  
-===== ๐Ÿ” ๋””๋ฒ„๊น… =====+**๋ธŒ๋ผ์šฐ์ €์—์„œ ํ…Œ์ŠคํŠธ:**ย 
 +  * ๋ธŒ๋ผ์šฐ์ € ์—ด๊ธฐย 
 +  * ''http://localhost:3000'' ์ ‘์†ย 
 +  * ์„œ๋ฒ„๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์‘๋‹ตํ•˜๋Š”์ง€ ํ™•์ธ
  
-**๋กœ๊ทธ ๋ ˆ๋ฒจ ์„ค์ •:**ย +**ํ„ฐ๋ฏธ๋„์—์„œ ํ…Œ์ŠคํŠธ:**ย 
-<code javascript>ย +<file bash>ย 
-// ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ ์ƒ์„ธ ๋กœ๊ทธ ์ถœ๋ ฅย +curl http://localhost:3000ย 
-if (process.env.NODE_ENV === 'development') {ย +</file>
-    console.log('๐Ÿ”ง ๊ฐœ๋ฐœ ๋ชจ๋“œ๋กœ ์‹คํ–‰ ์ค‘');ย +
-    console.log('๐Ÿ“Š ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰:', process.memoryUsage());ย +
-}ย +
-</code>+
  
-**์—๋Ÿฌ ํ•ธ๋“ค๋ง:**ย +----ย 
-<code javascript>ย +===== 9. ๋””๋ฒ„๊น… ๋ฐ ๋กœ๊น… =====ย 
-process.on('uncaughtException'(err) ={ย +ย 
-    console.error('โŒ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ ์˜ˆ์™ธ:', err);ย +==== 1) ์ฝ˜์†” ๋กœ๊น… ====ย 
-    process.exit(1);+ย 
 +<file javascript>ย 
 +// ๊ธฐ๋ณธ ๋กœ๊น…ย 
 +console.log('์ผ๋ฐ˜ ๋ฉ”์‹œ์ง€');ย 
 +console.error('์—๋Ÿฌ ๋ฉ”์‹œ์ง€');ย 
 +console.warn('๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€');ย 
 +ย 
 +// ๊ฐ์ฒด ๋กœ๊น…ย 
 +const gameData = { id: 1, name: '๋ฐ”๋‘‘ ๊ฒŒ์ž„' };ย 
 +console.log('๊ฒŒ์ž„ ๋ฐ์ดํ„ฐ:', gameData);ย 
 +ย 
 +// ์‹œ๊ฐ„๊ณผ ํ•จ๊ป˜ ๋กœ๊น…ย 
 +console.log(`${new Date().toISOString()} - ์„œ๋ฒ„ ์‹œ์ž‘๋จ`);ย 
 +</file>ย 
 +ย 
 +==== 2) ๋กœ๊น… ๋ฏธ๋“ค์›จ์–ด ====ย 
 +ย 
 +<file javascript>ย 
 +// ์š”์ฒญ ๋กœ๊น… ๋ฏธ๋“ค์›จ์–ดย 
 +app.use((req, res, next) => {ย 
 +    console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`);ย 
 +    next();
 }); });
  
-process.on('unhandledRejection', (reasonpromise) => {ย +// ์—๋Ÿฌ ๋กœ๊น… ๋ฏธ๋“ค์›จ์–ดย 
-    console.error('โŒ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ Promise ๊ฑฐ๋ถ€:', reason);+app.use((errreq, res, next) => {ย 
 +    console.error('์„œ๋ฒ„ ์—๋Ÿฌ:', err);ย 
 +    res.status(500).json({ error: '์„œ๋ฒ„ ๋‚ด๋ถ€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.' });
 }); });
-</code>+</file>ย 
 +ย 
 +==== 3) ๋””๋ฒ„๊น… ๋„๊ตฌ ====ย 
 +ย 
 +**Node.js ๋‚ด์žฅ ๋””๋ฒ„๊ฑฐ ์‚ฌ์šฉ:**ย 
 +<file bash>ย 
 +node --inspect server.jsย 
 +</file>ย 
 +ย 
 +**Chrome DevTools์—์„œ ๋””๋ฒ„๊น…:**ย 
 +  * Chrome ๋ธŒ๋ผ์šฐ์ € ์—ด๊ธฐย 
 +  * %%chrome://inspect%% ์ ‘์†ย 
 +  * "Open dedicated DevTools for Node" ํด๋ฆญย 
 +ย 
 +----ย 
 +===== 10. ์„ฑ๋Šฅ ์ตœ์ ํ™” =====ย 
 +ย 
 +==== 1) ์••์ถ• ์„ค์ • ====ย 
 +ย 
 +<file javascript>ย 
 +const compression = require('compression');ย 
 +ย 
 +// ์‘๋‹ต ์••์ถ• ๋ฏธ๋“ค์›จ์–ดย 
 +app.use(compression());ย 
 +</file>ย 
 +ย 
 +==== 2) ์บ์‹ฑ ์„ค์ • ====ย 
 +ย 
 +<file javascript>ย 
 +// ์ •์  ํŒŒ์ผ ์บ์‹ฑย 
 +app.use(express.static(path.join(dirname, 'public'), {ย 
 +    maxAge: '1d', // 1์ผ๊ฐ„ ์บ์‹œย 
 +    etag: true    // ETag ์‚ฌ์šฉย 
 +}));ย 
 +</file>ย 
 +ย 
 +==== 3) ์š”์ฒญ ์ œํ•œ ====ย 
 +ย 
 +<file javascript>ย 
 +const rateLimit = require('express-rate-limit');ย 
 +ย 
 +// API ์š”์ฒญ ์ œํ•œย 
 +const limiter = rateLimit({ย 
 +    windowMs: 15 * 60 * 1000, // 15๋ถ„ย 
 +    max: 100, // IP๋‹น ์ตœ๋Œ€ 100๊ฐœ ์š”์ฒญย 
 +    message: '๋„ˆ๋ฌด ๋งŽ์€ ์š”์ฒญ์ด ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.'ย 
 +});ย 
 +ย 
 +app.use('/api/', limiter);ย 
 +</file>ย 
 +ย 
 +----ย 
 +===== 11. ๋ณด์•ˆ ์„ค์ • =====ย 
 +ย 
 +==== 1) Helmet ๋ฏธ๋“ค์›จ์–ด ====
  
-===== ๐Ÿš€ ์„ฑ๋Šฅ ์ตœ์ ํ™” =====+<file javascript>ย 
 +const helmet require('helmet');
  
-**๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ:**ย +// ๋ณด์•ˆ ํ—ค๋” ์„ค์ •ย 
-<code javascript>ย +app.use(helmet({ย 
-// ์ฃผ๊ธฐ์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ์ •๋ฆฌย +    contentSecurityPolicy: {ย 
-setInterval(() => {ย +        directives: {ย 
-    if (global.gc) {ย +            defaultSrc: ["'self'"],ย 
-        global.gc();ย +            styleSrc: ["'self'", "'unsafe-inline'"],ย 
-        console.log('๐Ÿงน ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ์‹คํ–‰');+            scriptSrc: ["'self'", "'unsafe-inline'"],ย 
 +            imgSrc: ["'self'", "data:", "https:"],ย 
 +            connectSrc: ["'self'", "ws:", "wss:"]ย 
 +        }
     }     }
-}, 30000); // 30์ดˆ๋งˆ๋‹คย +}));ย 
-</code>+</file>
  
-**ํด๋Ÿฌ์Šคํ„ฐ ๋ชจ๋“œ:**ย +==== 2CORS ์„ค์ • ====
-<code javascript>ย +
-const cluster require('cluster');ย +
-const numCPUs require('os').cpus().length;+
  
-if (cluster.isMaster{ย +<file javascript>ย 
-    console.log(`๋งˆ์Šคํ„ฐ ํ”„๋กœ์„ธ์Šค ${process.pid์‹คํ–‰ ์ค‘`);+const cors = require('cors');ย 
 +ย 
 +// CORS ์„ค์ •ย 
 +app.use(cors({ย 
 +    origin: process.env.NODE_ENV === 'production' ย 
 +        ? ['https://yourdomain.com'] ย 
 +        : ['http://localhost:3000'],ย 
 +    credentials: trueย 
 +}));ย 
 +</file>ย 
 +ย 
 +==== 3) ์ž…๋ ฅ ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ ====ย 
 +ย 
 +<file javascript>ย 
 +// ์ž…๋ ฅ ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ ์˜ˆ์ œย 
 +app.post('/api/games', (req, res) => {ย 
 +    const { gameType, settings } = req.body;
          
-    // ์›Œ์ปค ํ”„๋กœ์„ธ์Šค ์ƒ์„ฑย +    // ํ•„์ˆ˜ ํ•„๋“œ ๊ฒ€์ฆย 
-    for (let i = 0; i < numCPUs; i++) {ย +    if (!gameType) {ย 
-        cluster.fork();+        return res.status(400).json({ error: '๊ฒŒ์ž„ ํƒ€์ž…์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.' });
     }     }
          
-    cluster.on('exit', (worker, code, signal=> {ย +    // ๋ฐ์ดํ„ฐ ํƒ€์ž… ๊ฒ€์ฆย 
-        console.log(`์›Œ์ปค ${worker.process.pid์ข…๋ฃŒ`);ย +    if (typeof gameType !== 'string') {ย 
-        cluster.fork(); // ์ƒˆ๋กœ์šด ์›Œ์ปค ์ƒ์„ฑย +        return res.status(400).json({ error: '๊ฒŒ์ž„ ํƒ€์ž…์€ ๋ฌธ์ž์—ด์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.});ย 
-    });ย +    }ย 
-} else {ย +    ย 
-    // ์›Œ์ปค ํ”„๋กœ์„ธ์Šค์—์„œ ์„œ๋ฒ„ ์‹คํ–‰ย +    // ์ถ”๊ฐ€ ์ฒ˜๋ฆฌ...ย 
-    require('./server.js');ย +});ย 
-}ย +</file>
-</code>+
  
-===== ๐Ÿ“š ๊ด€๋ จ ๋ฌธ์„œ =====+----ย 
 +===== 12. ๋‹ค์Œ ๋‹จ๊ณ„ =====
  
-  * [[wiki:it:dream_of_enc:metaverse:express|Express.js ์›น ํ”„๋ ˆ์ž„์›Œํฌ]]ย +''Node.js'' ๊ธฐ๋ณธ์„ ๋ฐฐ์› ๋‹ค๋ฉด ๋‹ค์Œ์„ ํ•™์Šตํ•ด๋ณด์„ธ์š”:ย 
-  [[wiki:it:dream_of_enc:metaverse:socketio|Socket.IO ์‹ค์‹œ๊ฐ„ ํ†ต์‹ ]]ย +ย 
-  [[wiki:it:dream_of_enc:metaverse:pm2|PM2 ํ”„๋กœ์„ธ์Šค ๊ด€๋ฆฌ]]+  **''Express.js''** - ์›น ํ”„๋ ˆ์ž„์›Œํฌ ์‹ฌํ™” ํ•™์Šตย 
 +  * **''Socket.IO''** - ์‹ค์‹œ๊ฐ„ ํ†ต์‹  ๊ตฌํ˜„ย 
 +  * **๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๋™** - ''MongoDB'', ''MySQL'' ๋“ฑย 
 +  * **์ธ์ฆ ์‹œ์Šคํ…œ** - ''JWT'', ''Passport.js'' ๋“ฑย 
 +  * **ํ…Œ์ŠคํŠธ ์ž‘์„ฑ** - ''Jest'', ''Mocha'' ๋“ฑย 
 +ย 
 +**์ถ”์ฒœ ํ•™์Šต ์ˆœ์„œ:**ย 
 +  - [[wiki:it:dream_of_enc:metaverse:express|๐Ÿš€ Express.js ์›น ํ”„๋ ˆ์ž„์›Œํฌ]]ย 
 +  [[wiki:it:dream_of_enc:metaverse:socketio|๐Ÿ”Œ Socket.IO ์‹ค์‹œ๊ฐ„ ํ†ต์‹ ]]ย 
 +  [[wiki:it:dream_of_enc:metaverse:pm2|โšก PM2 ํ”„๋กœ์„ธ์Šค ๊ด€๋ฆฌ]]
  
 --- ---
-//์ด ํŽ˜์ด์ง€๋Š” ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.// +//์ด ํŽ˜์ด์ง€๋Š” ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.//ย 
 +---ย 
wiki/it/dream_of_enc/metaverse/nodejs.1753682235.txt.gz ยท ๋งˆ์ง€๋ง‰์œผ๋กœ ์ˆ˜์ •๋จ: ์ €์ž 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki