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

Node.js连接节点验证客户端ID避免重复 实现点对点消息

解决客户端ID重复问题的方案

你当前用Math.floor(Math.random()*50)生成ID的方式存在两个核心问题:范围太小极易重复、无重复校验机制,这会直接影响后续点对点消息的准确性。下面提供两种可靠的解决方式,同时适配你现有代码做修改:

方法一:递增计数器(简单高效,绝对无重复)

适合小到中等规模的服务,实现成本极低且能保证ID唯一:

  1. 全局定义一个计数器变量,初始值设为1(或你需要的起始ID)
  2. 客户端连接时,直接将当前计数器值赋值给con.id,随后计数器自增

修改后的完整代码:

var broadcast = function (msg,origem){
  conexoes.forEach(function(con){
        if(con === origem) return;
        con.write(msg);
  });
};

// 新增全局ID计数器
let clientIdCounter = 1;
const conexoes = []; // 确保连接数组全局可访问

net.createServer(function(con){
    conexoes.push(con);
    // 替换随机ID为递增计数器
    con.id = clientIdCounter++;
    con.write("Servidor ativo.\n");
    
    con.on('data', function (msg) {
        var comando = msg.toString().trim();
        console.log("cmd-> " + comando);
        
        if(comando.indexOf('#name') === 0) {
            var nome = comando.replace('#name','').trim();
            // 优化昵称变更的提示文案
            broadcast((con.nome ? `${con.nome} agora se chama ` : 'Novo cliente ') + nome);
            con.nome = nome;
            return;
        };
        
        console.log('id->' + con.id);
        console.log('con-> '+con.nome);
        // 未设置昵称时用ID兜底显示
        broadcast((con.nome || `Cliente ${con.id}`) + ' -> ' + msg, con);
    });

    con.on('end',function () {
        broadcast((con.nome || `Cliente ${con.id}`) + ' saiu', con);
        conexoes.splice(conexoes.indexOf(con), 1); 
    })

    con.on('error', (e) => {
        if (e.code == 'ECONNRESET') { 
            console.log("Um cliente se desconectou");
            // 错误场景下也移除无效连接,避免内存泄漏
            const index = conexoes.indexOf(con);
            if (index !== -1) conexoes.splice(index, 1);
        }else{
            console.log(e.toString());
        }
    });
}).listen(1213);

方法二:UUID(适合分布式/大规模场景)

如果服务后续需要扩展为分布式架构,或者需要更复杂的唯一标识,可以使用uuid包生成全球唯一ID:

  1. 先安装依赖:npm install uuid
  2. 在代码中引入并替换ID生成逻辑:
const { v4: uuidv4 } = require('uuid');

// 客户端连接时替换为:
con.id = uuidv4();

UUID是字符串格式的唯一ID,完全不用担心重复问题,缺点是ID长度较长,若需要简洁数字ID,方法一更合适。

点对点消息辅助函数

为了方便后续根据ID查找客户端发送消息,可新增工具函数:

function getClientById(targetId) {
    return conexoes.find(con => con.id === targetId);
}

// 使用示例:给ID为3的客户端发消息
const targetClient = getClientById(3);
if (targetClient) {
    targetClient.write('这是专属你的点对点消息');
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 05:05:53