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

使用带中间件的动态命名空间时Socket.io重复处理首个客户端

Socket.io动态命名空间中间件异常:重复调用首个客户端Socket对象

异常现象

在Socket.io中注册动态命名空间时,中间件会重复输出首个客户端的Cookie信息,而非对应新连接客户端的内容;仅保留首个客户端连接时,输出结果正常。

复现环境

  • Socket.io服务端/客户端 4.5.4
  • Node.js v16.15.0

复现代码

const { io } = require('socket.io-client');
const { Server } = require('socket.io');

const server = new Server(4321, {});

function middleware(socket, next) {
  console.log(socket.nsp.name, socket.handshake.headers.cookie);
}

server.on('new_namespace', (namespace) => {
  namespace.use(middleware);
})

const nsps = server.of(/^\/\w+$/);

const clientOne = io.connect('http://localhost:4321/firstNamespace', {
  extraHeaders: {
    Cookie: "client=one"
  }
});

const clientTwo = io.connect('http://localhost:4321/secondNamespace', {
  extraHeaders: {
    Cookie: "client=two"
  }
});

const clientThree = io.connect('http://localhost:4321/thirdNamespace', {
  extraHeaders: {
    Cookie: "client=three"
  }
});

运行输出

/firstNamespace client=one
/secondNamespace client=one
/thirdNamespace client=one

原因分析与解决方案

异常原因

原代码错误地通过new_namespace事件为每个动态生成的命名空间绑定中间件。Socket.io中,正则匹配的动态命名空间由server.of(/^\/\w+$/)返回的DynamicNamespace统一管理,new_namespace事件会在每个具体命名空间(如/firstNamespace)创建时触发,但此时绑定中间件会导致Socket.io内部复用首个客户端的socket上下文,从而输出错误的握手信息。

解决方案

直接给动态命名空间实例绑定中间件,而非通过new_namespace事件逐个绑定:

const { io } = require('socket.io-client');
const { Server } = require('socket.io');

const server = new Server(4321, {});

function middleware(socket, next) {
  console.log(socket.nsp.name, socket.handshake.headers.cookie);
  next(); // 必须调用next()完成中间件流程,否则客户端连接会挂起
}

// 直接为动态命名空间绑定中间件
const dynamicNsp = server.of(/^\/\w+$/);
dynamicNsp.use(middleware);

const clientOne = io.connect('http://localhost:4321/firstNamespace', {
  extraHeaders: {
    Cookie: "client=one"
  }
});

const clientTwo = io.connect('http://localhost:4321/secondNamespace', {
  extraHeaders: {
    Cookie: "client=two"
  }
});

const clientThree = io.connect('http://localhost:4321/thirdNamespace', {
  extraHeaders: {
    Cookie: "client=three"
  }
});

修改后控制台会输出正确结果:

/firstNamespace client=one
/secondNamespace client=two
/thirdNamespace client=three

内容的提问来源于stack exchange,提问作者Carcigenicate

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 15:05:17