You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从主应用初始化脚本外的位置及不同脚本触发Socket.io事件?

Socket.io 跨脚本事件触发解决方案

一、从主初始化脚本外触发事件

核心是把初始化好的io实例导出,让其他脚本直接引用调用,不用重复初始化Socket.io。

实际项目示例:

  1. 主初始化脚本(app.js):
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');

const app = express();
const server = http.createServer(app);
// 初始化io实例
const io = new Server(server, {
  cors: { origin: "http://localhost:5173" } // 按需配置跨域规则
});

// 导出io实例供其他文件调用
module.exports = { io };

// 监听连接事件
io.on('connection', (socket) => {
  console.log(`用户 ${socket.id} 已连接`);
  socket.on('disconnect', () => {
    console.log(`用户 ${socket.id} 已断开`);
  });
});

server.listen(3000, () => {
  console.log('服务运行在 http://localhost:3000');
});
  1. 业务逻辑脚本(比如orderService.js):
// 导入主脚本导出的io实例
const { io } = require('./app');

// 订单状态更新时触发Socket.io事件
exports.updateOrderStatus = (orderId, status) => {
  // 先执行业务逻辑:更新数据库订单状态...
  
  // 触发全局事件通知所有客户端
  io.emit('order_updated', { orderId, status });
  
  // 给特定房间/用户发送的写法:
  // io.to(`order_${orderId}`).emit('order_status_change', { status });
};

二、在不同脚本中导出并触发事件

可以把Socket.io事件触发逻辑封装成工具函数统一导出,其他脚本直接调用,让代码更模块化、易维护。

示例步骤:

  1. 工具脚本(socketUtils.js):
const { io } = require('./app');

// 封装全局通知函数
exports.sendGlobalAlert = (content) => {
  io.emit('global_alert', {
    content,
    time: new Date().toLocaleString()
  });
};

// 维护用户ID与socket.id的映射(生产环境建议用Redis替代内存Map)
const userSocketMap = new Map();

// 导出添加映射的方法(在主脚本连接事件中调用)
exports.addUserSocket = (userId, socketId) => {
  userSocketMap.set(userId, socketId);
};

// 导出私信发送方法
exports.sendPrivateMessage = (userId, message) => {
  const socketId = userSocketMap.get(userId);
  if (socketId) {
    io.to(socketId).emit('private_msg', { message });
  }
};
  1. 主脚本中绑定用户映射:
// app.js 的connection事件中
const { addUserSocket } = require('./socketUtils');

io.on('connection', (socket) => {
  // 假设客户端连接时会发送userId
  socket.on('user_login', (userId) => {
    addUserSocket(userId, socket.id);
  });
  
  // 用户断开时移除映射
  socket.on('disconnect', () => {
    for (const [userId, id] of userSocketMap.entries()) {
      if (id === socket.id) {
        userSocketMap.delete(userId);
        break;
      }
    }
  });
});
  1. 业务脚本中调用工具函数:
// 用户服务脚本 userService.js
const { sendPrivateMessage } = require('./socketUtils');

exports.userSignedUp = (userId) => {
  // 业务逻辑:创建用户账号...
  
  // 给新用户发送欢迎私信
  sendPrivateMessage(userId, '欢迎注册!请完善你的个人信息');
};

内容的提问来源于stack exchange,提问作者Руслан Миров

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 21:50:37