Node.js连接节点验证客户端ID避免重复 实现点对点消息
解决客户端ID重复问题的方案
你当前用Math.floor(Math.random()*50)生成ID的方式存在两个核心问题:范围太小极易重复、无重复校验机制,这会直接影响后续点对点消息的准确性。下面提供两种可靠的解决方式,同时适配你现有代码做修改:
方法一:递增计数器(简单高效,绝对无重复)
适合小到中等规模的服务,实现成本极低且能保证ID唯一:
- 全局定义一个计数器变量,初始值设为1(或你需要的起始ID)
- 客户端连接时,直接将当前计数器值赋值给
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:
- 先安装依赖:
npm install uuid - 在代码中引入并替换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
相关产品推荐
相关产品推荐

