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

Node.js net.createServer多连接异常问题求助

问题根源:客户端实例管理错误,不是服务器不支持多连接

别担心,Node.js的net.createServer本身完全能处理多客户端连接,你的问题出在代码里对客户端实例的管理上,具体是这几个坑:

  • 全局变量覆盖客户端实例:你用了global.clientObjz这个全局变量存储每个新连接的客户端实例。每次有新客户端连进来,这个全局变量就会被替换成新的client对象。结果就是,当第一个客户端发送数据时,代码里引用的clientObjz已经是第二个客户端的实例了,所以第一个客户端的操作会直接作用在第二个客户端上,这就是你看到“第一个可控制第二个”的原因。

  • 未正确传入当前客户端实例:在Game[method](data, client);这行里,client变量根本没定义!哪怕你想用全局的clientObjz,这里也写错了变量名,而且就算写对了,因为全局变量被覆盖,也会用错实例。

  • 移除客户端时用错对象:addClient方法是把client对象加入到客户端列表,但socket.on('end')里却调用game.removeClient(socket);,传入的是socket而不是对应的client实例。这样服务器的客户端列表里永远不会移除正确的对象,时间长了会积累无效实例,还可能导致断开逻辑出错。


修复步骤

1. 去掉全局变量,用本地变量存储客户端实例

把每个连接的client实例存在socket回调的本地作用域里,避免全局覆盖:

var server = net.createServer(function(socket) {
  console.log('A client has connected' + "\r\n");
  socket.setEncoding('utf8')
  // 用本地变量存储当前客户端实例
  const clientObj = new client(socket); 
  game.addClient(clientObj);

  socket.on('data', function(data) {
    data = data.toString().split('\0')[0];
    console.log('Incoming data: ' + data + "\r\n")
    if (data == "<msg t='sys'><body action='verChk' r='0'><ver v='153' /></body></msg>" || data == "<msg t='sys'><body action='rndK' r='-1'></body></msg>" || data.startsWith("<msg t='sys'><body action='login' r='0'>")) {
      parseXml(data, function(err, result) {
        var type = result.msg['$'].t, action = result.msg.body[0]['$'].action;
        var method = Game.xmlHandlers[type][action];
        if (typeof Game[method] == 'function') {
          // 传入当前的clientObj,替换未定义的client变量
          Game[method](data, clientObj); 
        }
      });
    }
    var dataType = data.charAt(0);
    if (dataType == '%') {
      // 用本地的clientObj处理数据,确保对应正确的客户端
      game.handleraw(data, clientObj); 
    }
  });

  socket.on('end', function() {
    // 传入对应的client实例,而不是socket
    game.removeClient(clientObj); 
    console.log('A client has disconnected');
  });

  socket.on('error', function(err) {
    console.log(err);
    // 出错时也要正确移除客户端实例
    game.removeClient(clientObj);
  });
});

2. 修复removeClient方法,确保移除正确的实例

修改game对象的removeClient方法,找到数组中对应的client实例并移除:

// 假设self是game对象的上下文
removeClient: function(client) {
  // 找到客户端在数组中的索引
  const clientIndex = self.clients.findIndex(c => c === client);
  if (clientIndex !== -1) {
    // 从数组中移除该实例
    self.clients.splice(clientIndex, 1);
  }
}

3. 检查client类的实现

确保你的client类每个实例都独立绑定自己的socket,没有共享状态的问题——比如不要在client类里用全局变量存储socket或客户端数据,每个实例用自己的属性。


总结

你的问题和net.createServer的多连接支持无关,完全是代码中对客户端实例的管理错误导致的:全局变量覆盖实例、参数传递错误、移除实例时对象不匹配。修复这些点后,多个客户端就能独立连接和操作,不会出现互相控制或异常断开的问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:42:23