Angular中Socket.io多命名空间连接冲突问题及解决方法咨询
解决Socket.io双命名空间连接互相覆盖的问题
问题根源分析
你的代码存在两处关键错误,导致命名空间连接异常:
- 服务端
simulator1_Namespace的连接回调中,错误使用了未定义的sockets2变量(应为当前连接的socket实例),触发运行时错误后导致第一个命名空间连接意外中断。 - 服务端未定义
IPADDRESS变量,可能导致Socket服务监听失败,间接引发连接异常。 - CORS配置存在冗余,
allowedHeaders中配置的是响应头而非请求头,可能影响跨域连接稳定性。
修复步骤
1. 服务端代码修复
const express = require('express'); const cors = require('cors'); const appExpress = express(); appExpress.use(cors()); appExpress.use(express.json()); appExpress.use(express.urlencoded({ extended: true })); const PORT_SOCKET = 4001; const IPADDRESS = '0.0.0.0'; // 监听所有可用IP,或替换为你的具体IP appExpress.get('/', (req, res) => { res.json({ message: 'Welcome to application.' }); }); const socketServer = require('http').Server(appExpress); const io = require('socket.io')(socketServer, { cors: { origin: '*', // 生产环境建议指定具体域名 credentials: true, // 允许携带凭证,关键配置 methods: ["GET", "POST"] }, }); socketServer.listen(PORT_SOCKET, IPADDRESS, function () { console.log(`listening on ${IPADDRESS}:${PORT_SOCKET}`); }); const simulator1_Namespace = io.of('/CGI_ONE'); const simulator2_Namespace = io.of('/CGI_TWO'); simulator1_Namespace.on('connection', function (socket) { console.log('CGI_ONE 命名空间有客户端连接'); // 修正笔误:使用当前socket实例监听事件 socket.on('SOURCE', function (SOURCE) { console.log('CGI_ONE 收到SOURCE:', SOURCE); }); socket.on('disconnect', () => { console.log('CGI_ONE 客户端断开连接'); }); }); simulator2_Namespace.on('connection', function (socket) { console.log('CGI_TWO 命名空间有客户端连接'); socket.on('SOURCE', function (SOURCE) { console.log('CGI_TWO 收到SOURCE:', SOURCE); }); socket.on('disconnect', () => { console.log('CGI_TWO 客户端断开连接'); }); });
2. 客户端代码优化
Angular中确保Socket实例正确初始化,若存在连接复用问题,可显式配置forceNew: true强制创建新连接(Socket.io默认支持同一连接下多命名空间,此配置为兜底方案):
import { Injectable } from '@angular/core'; import { io, Socket } from 'socket.io-client'; @Injectable({ providedIn: 'root' }) export class NsSocketsService { socketCGI_ONE: Socket; socketCGI_TWO: Socket; constructor() { const socketOptions = { credentials: true, // forceNew: true, // 若仍有问题,取消注释此配置 }; this.socketCGI_ONE = io("http://192.168.5.116:4001/CGI_ONE", socketOptions); this.socketCGI_TWO = io("http://192.168.5.116:4001/CGI_TWO", socketOptions); this.socketCGI_ONE.on('connect', () => { console.log('CGI_ONE 连接成功'); this.socketCGI_ONE.emit('SOURCE', 'SESSION'); }); this.socketCGI_TWO.on('connect', () => { console.log('CGI_TWO 连接成功'); this.socketCGI_TWO.emit('SOURCE', 'SESSION'); }); // 监听断开事件,便于排查问题 this.socketCGI_ONE.on('disconnect', () => { console.log('CGI_ONE 断开连接'); }); this.socketCGI_TWO.on('disconnect', () => { console.log('CGI_TWO 断开连接'); }); } }
验证方法
启动服务端后运行Angular应用,查看服务端控制台:
- 应先后打印
CGI_ONE 命名空间有客户端连接和CGI_TWO 命名空间有客户端连接 - 同时收到两个命名空间发来的
SOURCE: SESSION消息 - 客户端控制台无断开连接日志
内容的提问来源于stack exchange,提问作者Vipul S
相关产品推荐
相关产品推荐

