From 9dc9066218a2de78dc05dfd4a39ba6c2336f52f0 Mon Sep 17 00:00:00 2001 From: jangyeeunee Date: Fri, 14 Feb 2025 12:57:28 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20socket=20=EB=AF=B8=EB=93=A4?= =?UTF-8?q?=EC=9B=A8=EC=96=B4=20=EC=9D=BC=EB=8B=A8=20=EC=83=9D=EC=84=B1..?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 226 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + src/index.js | 11 ++- 3 files changed, 235 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 15110af..bb24cd7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "mysql2": "^3.12.0", "nodemailer": "^6.10.0", "passport": "^0.7.0", + "socket.io": "^4.8.1", "swagger-autogen": "^2.23.7", "swagger-ui-express": "^5.0.1", "uuid": "^11.0.5" @@ -1628,6 +1629,30 @@ "node": ">=18.0.0" } }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "license": "MIT" + }, + "node_modules/@types/cors": { + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "22.13.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz", + "integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -1761,6 +1786,15 @@ } ] }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "license": "MIT", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, "node_modules/bcrypt": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", @@ -2177,6 +2211,87 @@ "node": ">= 0.8" } }, + "node_modules/engine.io": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz", + "integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==", + "license": "MIT", + "dependencies": { + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.7.2", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io/node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/engine.io/node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/engine.io/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/engine.io/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/engine.io/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -3734,6 +3849,90 @@ "node": ">=10" } }, + "node_modules/socket.io": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", + "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.6.0", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", + "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", + "license": "MIT", + "dependencies": { + "debug": "~4.3.4", + "ws": "~8.17.1" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io/node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/socket.io/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/socket.io/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/socket.io/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/sqlstring": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", @@ -3968,6 +4167,12 @@ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "dev": true }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "license": "MIT" + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -4036,6 +4241,27 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index d9a92bb..1a91459 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "mysql2": "^3.12.0", "nodemailer": "^6.10.0", "passport": "^0.7.0", + "socket.io": "^4.8.1", "swagger-autogen": "^2.23.7", "swagger-ui-express": "^5.0.1", "uuid": "^11.0.5" diff --git a/src/index.js b/src/index.js index 96292d0..368a7e1 100644 --- a/src/index.js +++ b/src/index.js @@ -18,7 +18,7 @@ import { handleGetPostLiked } from "./controllers/post.controller.js"; import { handleSignUp, handleLogin, handlecheckEmail, handleTokenRefresh, handlesendEmail, handleNewPassword, handlerGetUserEmail, handleVerifyData } from "./controllers/auth.controller.js"; import { authenticateJWT } from "./auth.middleware.js"; import { imageUploader } from "../middleware.js"; - +import { Server } from 'socket.io'; dotenv.config(); const app = express(); @@ -243,6 +243,8 @@ app.get('/myPage',authenticateJWT ,handlerShowUserInfo) // 템플릿 설문 작성 app.post('/templates/:templateId/survey',authenticateJWT, handlerCreateTemplateSurvey) +app.post('/chats/create',) + /****************전역 오류를 처리하기 위한 미들웨어*******************/ app.use((err, req, res, next) => { if (res.headersSent) { @@ -255,9 +257,12 @@ app.use((err, req, res, next) => { data: err.data || null, }); }); + /****************전역 오류를 처리하기 위한 미들웨어*******************/ -app.listen(port, () => { +const server = app.listen(port, () => { console.log(`Example app listening on port ${port}`); -}) \ No newline at end of file +}); + +const io = new Server(server, { path: '/socket.io' }); \ No newline at end of file From 8a4fa82438f601e9c85673983bbaca7f0a7bd50b Mon Sep 17 00:00:00 2001 From: jangyeeunee Date: Fri, 14 Feb 2025 13:06:56 +0900 Subject: [PATCH 2/4] =?UTF-8?q?=EB=AF=B8=EB=93=A4=EC=9B=A8=EC=96=B4=20?= =?UTF-8?q?=EC=95=88=EB=93=A4=EC=96=B4=EA=B0=94=EB=82=98..=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/chat.middleware.js | 55 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/chat.middleware.js diff --git a/src/chat.middleware.js b/src/chat.middleware.js new file mode 100644 index 0000000..a14a976 --- /dev/null +++ b/src/chat.middleware.js @@ -0,0 +1,55 @@ +import { Server } from 'socket.io'; + +let io; + +/* + 사용자가 소켓을 열면 소켓주소가 부여되는데 이게 연결을 끊고 다시 열면 새로운 주소가 부여됨 -> map으로 userId를 키, socketid를 value로 두고 하면딜거 같아여.. + 더 나은 방법있으면 알려주세용 +*/ +const userSockets = new Map(); + +// ✅ 서버 실행 시 소켓 초기화 +export const initSocket = (server) => { + io = new Server(server, { path: '/socket.io' }); + + io.on('connection', (socket) => { + console.log(`소켓 연결됨: ${socket.id}`); + + // 사용자 정보 저장 + socket.on('register', (userId) => { + console.log(`🔗 사용자 ${userId} 소켓 연결`); + socket.userId = userId; + userSockets.set(userId, socket); + }); + + socket.on('disconnect', () => { + console.log(`소켓 연결 해제됨: ${socket.id}`); + userSockets.delete(socket.userId); + }); + }); +}; + +//소켓을 API 호출 전에 자동으로 설정 +export const socketMiddleware = (req, res, next) => { + if (!io) { + return res.status(500).send('소켓 서버가 아직 초기화되지 않았습니다.'); + } + + // 이부분 지피티가 짜줬는데 미들웨어에서 이렇게 에러처리 해도 괜찮을라나..? + const userId = req.user?.id; // JWT 인증된 사용자 ID + if (!userId) { + return res.status(401).send('사용자 인증이 필요합니다.'); + } + + let socket = userSockets.get(userId); + + if (!socket) { + return res.status(400).send('소켓 연결이 필요합니다.'); + } + + req.io = io; // 소켓 서버 객체 저장 + req.socketId = socket.id; // 사용자 소켓 ID 저장 + req.roomId = req.body.roomId || null; // 채팅방 ID 저장 + + next(); +}; \ No newline at end of file From d9c4255b4caaffea497113686da08f8cd55cc173 Mon Sep 17 00:00:00 2001 From: taehun kang Date: Sat, 15 Feb 2025 15:13:39 +0900 Subject: [PATCH 3/4] =?UTF-8?q?:recycle:=20[refator]=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=ED=8C=8C=EC=9D=BC=20=EC=B6=94=EA=B0=80=20=EB=B0=8F?= =?UTF-8?q?=20index=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EB=B2=84=EA=B7=B8?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/chat.controller.js | 0 testClient.js | 17 +++++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 src/controllers/chat.controller.js create mode 100644 testClient.js diff --git a/src/controllers/chat.controller.js b/src/controllers/chat.controller.js new file mode 100644 index 0000000..e69de29 diff --git a/testClient.js b/testClient.js new file mode 100644 index 0000000..8185371 --- /dev/null +++ b/testClient.js @@ -0,0 +1,17 @@ +import { io } from 'socket.io-client'; + +const socket = io('http://localhost:3000', { path: '/socket.io' }); + +socket.on('connect', () => { + console.log('✅ 서버 연결됨:', socket.id); + socket.emit('register', 'testUser'); // 사용자 ID 등록 +}); + +socket.on('disconnect', () => { + console.log('❌ 서버와 연결 해제됨'); +}); + +setTimeout(() => { + console.log('📨 5초 후 연결 종료'); + socket.disconnect(); +}, 5000); From 919ad62f3a17de7711eddacd114ce8c963380e1b Mon Sep 17 00:00:00 2001 From: taehun kang Date: Sat, 15 Feb 2025 15:13:54 +0900 Subject: [PATCH 4/4] =?UTF-8?q?:recycle:=20[refator]=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=ED=8C=8C=EC=9D=BC=20=EC=B6=94=EA=B0=80=20=EB=B0=8F?= =?UTF-8?q?=20index=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EB=B2=84=EA=B7=B8?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 37 +++++++++++++++++++++++++++ package.json | 1 + src/chat.middleware.js | 4 +-- src/controllers/chat.controller.js | 6 +++++ src/index.js | 40 +++++++++++++++++++++++++++--- testClient.js | 22 +++++++++++++--- 6 files changed, 102 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index bb24cd7..4245541 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "nodemailer": "^6.10.0", "passport": "^0.7.0", "socket.io": "^4.8.1", + "socket.io-client": "^4.8.1", "swagger-autogen": "^2.23.7", "swagger-ui-express": "^5.0.1", "uuid": "^11.0.5" @@ -2231,6 +2232,19 @@ "node": ">=10.2.0" } }, + "node_modules/engine.io-client": { + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.3.tgz", + "integrity": "sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1", + "xmlhttprequest-ssl": "~2.1.1" + } + }, "node_modules/engine.io-parser": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", @@ -3877,6 +3891,21 @@ "ws": "~8.17.1" } }, + "node_modules/socket.io-client": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz", + "integrity": "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.6.1", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/socket.io-parser": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", @@ -4262,6 +4291,14 @@ } } }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", + "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index 1a91459..68b57c6 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "nodemailer": "^6.10.0", "passport": "^0.7.0", "socket.io": "^4.8.1", + "socket.io-client": "^4.8.1", "swagger-autogen": "^2.23.7", "swagger-ui-express": "^5.0.1", "uuid": "^11.0.5" diff --git a/src/chat.middleware.js b/src/chat.middleware.js index a14a976..7690860 100644 --- a/src/chat.middleware.js +++ b/src/chat.middleware.js @@ -34,9 +34,9 @@ export const socketMiddleware = (req, res, next) => { if (!io) { return res.status(500).send('소켓 서버가 아직 초기화되지 않았습니다.'); } - + console.log(req.user) // 이부분 지피티가 짜줬는데 미들웨어에서 이렇게 에러처리 해도 괜찮을라나..? - const userId = req.user?.id; // JWT 인증된 사용자 ID + const userId = req.user?.userId; // JWT 인증된 사용자 ID if (!userId) { return res.status(401).send('사용자 인증이 필요합니다.'); } diff --git a/src/controllers/chat.controller.js b/src/controllers/chat.controller.js index e69de29..b96e331 100644 --- a/src/controllers/chat.controller.js +++ b/src/controllers/chat.controller.js @@ -0,0 +1,6 @@ + + + +// export const handlerSendMessage = (req, res) => { +// +// } \ No newline at end of file diff --git a/src/index.js b/src/index.js index 368a7e1..94d9567 100644 --- a/src/index.js +++ b/src/index.js @@ -19,11 +19,35 @@ import { handleSignUp, handleLogin, handlecheckEmail, handleTokenRefresh, handle import { authenticateJWT } from "./auth.middleware.js"; import { imageUploader } from "../middleware.js"; import { Server } from 'socket.io'; +import { createServer } from 'http'; +import {initSocket, socketMiddleware} from "./chat.middleware.js"; + dotenv.config(); const app = express(); + +// express와 http서버를 분리함, 이걸 통해서 소켓을 추가할 수 있게됨 +const server = createServer(app); + +initSocket(server); + +/* +* http서버란? +* - 클라이언트로부터 HTTP요청을받고 응답을 보내는 역할을 하는 프로그램 +* +* Express란? +* - get, post, use 같은 요청에 대한 라우팅 처리, 미들웨어 추가 +* - 즉, nodejs기반 HTTP요청을 더 쉽게 처리할 수 있게 도와주는 프레임 워크 +* +* 소켓 추가하려면 어떻게 해야할까? +* - HTTP서버를 더 개조해야함 +* - app.listen으로는 소켓 추가 불가 +* */ + const port = process.env.PORT; + + /*****************공통 응답을 사용할 수 있는 헬퍼 함수 등록*********************/ app.use((req, res, next) => { res.success = (success) => { @@ -243,7 +267,18 @@ app.get('/myPage',authenticateJWT ,handlerShowUserInfo) // 템플릿 설문 작성 app.post('/templates/:templateId/survey',authenticateJWT, handlerCreateTemplateSurvey) -app.post('/chats/create',) +// app.post('/chats/create',) + +app.post('/send-message',authenticateJWT, socketMiddleware, (req,res)=>{ + const { message } = req.body + + const socket = req.io.sockets.sockets.get(req.socketId); + if(socket){ + socket.emit('newMessage', message); + } + + res.send({ success: true, message: '메시지 전송됨'}) +}) /****************전역 오류를 처리하기 위한 미들웨어*******************/ app.use((err, req, res, next) => { @@ -261,8 +296,7 @@ app.use((err, req, res, next) => { /****************전역 오류를 처리하기 위한 미들웨어*******************/ -const server = app.listen(port, () => { +server.listen(port, () => { console.log(`Example app listening on port ${port}`); }); -const io = new Server(server, { path: '/socket.io' }); \ No newline at end of file diff --git a/testClient.js b/testClient.js index 8185371..7e8553d 100644 --- a/testClient.js +++ b/testClient.js @@ -4,14 +4,30 @@ const socket = io('http://localhost:3000', { path: '/socket.io' }); socket.on('connect', () => { console.log('✅ 서버 연결됨:', socket.id); - socket.emit('register', 'testUser'); // 사용자 ID 등록 + + //사용자를 서버에 등록할 때 사용 + socket.emit('register', 'userId'); }); + + socket.on('disconnect', () => { console.log('❌ 서버와 연결 해제됨'); }); +// 서버에서 메시지 받으면 출력 +socket.on('newMessage', (msg) => { + console.log('📩 서버로부터 메시지:', msg); +}); + +// 3초 후 서버에 테스트 메시지 전송 +setTimeout(() => { + console.log('📨 메시지 전송: "테스트 메시지!"'); + socket.emit('send-message', { message: '테스트 메시지!' }); +}, 3000); + +// 강제 연결 종료 setTimeout(() => { - console.log('📨 5초 후 연결 종료'); + console.log('📨 10초 후 연결 종료'); socket.disconnect(); -}, 5000); +}, 10000);