如何在Express.js中借助Socket.io检测窗口关闭并更新MongoDB?
核心问题分析
你原来的代码无法运行的原因有三个:
disconnect事件回调中没有直接的req对象,无法直接获取Cookie- 使用
await但未将回调声明为async函数 - 变量名拼写不一致(
idCode和idcode)
实现步骤
配置Socket.io允许接收Cookie
确保服务器端启用Cookie解析中间件,并在Socket.io初始化时配置跨域凭证:const express = require('express'); const cookieParser = require('cookie-parser'); const { createServer } = require('http'); const { Server } = require('socket.io'); const app = express(); app.use(cookieParser()); // 启用Cookie解析 const httpServer = createServer(app); const io = new Server(httpServer, { cors: { origin: "你的前端域名", // 替换为实际前端地址 credentials: true // 允许携带凭证(Cookie) } });连接时存储Cookie到Socket实例
在connection事件中,从握手请求里获取Cookie并绑定到当前socket对象上:const account = require('./server/models/account'); // 提前引入模型,避免重复加载 io.on('connection', (socket) => { // 从握手请求中获取Cookie const idCode = socket.handshake.req.cookies.idcode; if (idCode) { socket.idCode = idCode; // 存到socket实例,供disconnect时使用 } // 断开连接事件处理 socket.on('disconnect', async () => { if (socket.idCode) { try { await account.updateOne({ Code: socket.idCode }, { response: 'yes' }); console.log('数据库更新成功'); } catch (err) { console.error('更新失败:', err); } } }); });
关键说明
- 提前引入
account模型,不要在事件回调里重复require,避免性能问题 - 增加错误捕获,防止数据库操作失败导致服务器异常
- 前端建立Socket连接时需开启
withCredentials:// 前端Socket连接代码 const socket = io('你的后端地址', { withCredentials: true });
内容的提问来源于stack exchange,提问作者Arusu
相关产品推荐
相关产品推荐

