Express.js应用集成Socket.io最佳方案:文件分离下实例化与跨模块复用
首先安装Socket.io依赖:
npm install socket.io
最佳实现方案
1. 改造server.js,挂载Socket.io并导出实例
你需要先拿到express启动后的http服务器实例,再用这个实例初始化Socket.io,最后把io实例对外导出,其他模块直接导入即可使用。
改后的server.js代码如下:
const app = require("./app"); const mongoose = require("mongoose"); const { Server } = require("socket.io"); let io; // 声明io实例变量 mongoose .connect(`mongodb://localhost:27017/${process.env.DATABASE}`) .then(() => { // 拿到http服务器实例 const server = app.listen(process.env.PORT); // 初始化Socket.io,可根据需求配置跨域等参数 io = new Server(server, { cors: { origin: "*" // 生产环境请替换为前端实际地址 } }); }) .catch((err) => { console.error(`connection failed: ${err}`); }); // 导出io实例,供其他模块调用 module.exports = { io };
2. 业务逻辑解耦(可选推荐)
如果Socket相关逻辑比较多,不要全部堆在server.js里,可以单独抽离为处理模块,比如新建socket/handler.js:
// socket/handler.js const initSocketHandlers = (io) => { io.on("connection", (socket) => { // 监听用户发送消息事件 socket.on("sendMessage", (data) => { // 广播消息给所有用户 io.emit("receiveMessage", data); }); // 其他事件监听... socket.on("disconnect", () => { console.log("用户断开连接:", socket.id); }); }); }; module.exports = initSocketHandlers;
然后在server.js里引入并调用即可:
const initSocketHandlers = require("./socket/handler"); // 省略其他代码... io = new Server(server, { cors: { origin: "*" } }); // 初始化所有socket事件处理逻辑 initSocketHandlers(io);
3. 其他模块调用io实例
比如你在express路由、数据库回调等其他业务场景需要主动推送消息时,直接导入server.js导出的io实例即可使用。
举个例子,新建routes/notice.js路由文件:
const express = require("express"); const router = express.Router(); // 导入io实例 const { io } = require("../server"); router.post("/sendAll", (req, res) => { const { content } = req.body; // 给所有在线用户推送系统通知 io.emit("systemNotice", { content }); res.send("通知已推送"); }); module.exports = router;
再把这个路由挂载到app.js里即可正常使用。
注意事项
- 调用io实例时要注意启动顺序,确保mongodb连接成功、服务器启动、io完成初始化后再调用,避免出现undefined报错
- 生产环境下请严格配置Socket.io的cors规则,不要使用
*通配符
内容的提问来源于stack exchange,提问作者Farid Ghaderi
相关产品推荐
相关产品推荐

