如何在Node.js的Socket.IO服务端实现全服在线用户列表展示功能
全服在线玩家列表实现方案
服务端代码修改
你需要在现有逻辑基础上增加用户列表广播、断开连接清理、主动拉取列表三个逻辑,修改后的完整服务端相关代码如下:
// 原有全局users数组保留 const users = []; // 新增:广播全服最新在线用户列表的公共函数 function broadcastOnlineUsers() { // 仅返回前端需要的公开字段,避免信息泄露 const publicUsers = users.map(user => ({ name: user.name, room: user.room, id: user.id })) // io为Socket.IO全局实例,若在连接回调内也可以用socket.server.emit替代 io.emit('onlineUsersUpdate', publicUsers) } function sendName(name) { var isNameValid = true; for (var i = 0; i < users.length; i++) { if (users[i].name === name) { isNameValid = false; console.log(name + " is already taken"); console.log(users); socket.emit("nameError", "Name already exists, Try again"); return; } } if (isNameValid) { var room = generateRoomId(); users.push({ id: socket.id, name: name, room: room }); socket.join(room); socket.emit("roomId", room); // 新增:新用户加入后广播全服最新列表 broadcastOnlineUsers() } } // 新增:监听用户断开连接事件,自动清理用户列表 socket.on('disconnect', () => { const index = users.findIndex(user => user.id === socket.id) if (index !== -1) { users.splice(index, 1) // 广播更新后的用户列表 broadcastOnlineUsers() } }) // 新增:监听客户端主动拉取用户列表的请求 socket.on('getOnlineUsers', () => { const publicUsers = users.map(user => ({ name: user.name, room: user.room, id: user.id })) socket.emit('onlineUsersUpdate', publicUsers) })
客户端代码实现
处理列表渲染、点击发起对战的逻辑如下:
// 你原有Socket连接初始化逻辑保留 const socket = io(); // 监听服务端推送的在线用户列表更新,自动刷新页面列表 socket.on('onlineUsersUpdate', (userList) => { const userUl = document.getElementById('users') // 清空原有列表 userUl.innerHTML = '' // 遍历渲染所有在线用户 userList.forEach(user => { const li = document.createElement('li') li.textContent = user.name // 存储目标用户信息,用于后续发起对战请求 li.dataset.targetId = user.id li.dataset.targetRoom = user.room // 点击玩家触发对战请求 li.addEventListener('click', () => { // 可自行补充二次确认逻辑 socket.emit('sendBattleRequest', { targetId: user.id, targetName: user.name, // 替换为你本地存储的当前登录用户名 senderName: localStorage.getItem('currentUserName') }) alert(`已向${user.name}发送对战请求`) }) userUl.appendChild(li) }) }) // 在线对战按钮点击事件,主动拉取最新列表 // 注意将battleBtn替换为你实际的按钮ID document.getElementById('battleBtn').addEventListener('click', () => { socket.emit('getOnlineUsers') // 可在此补充展示在线玩家列表弹窗的逻辑 })
补充说明
- 对战请求的服务端转发逻辑,只需通过请求携带的targetId找到对应用户的socket实例,单独给该用户推送邀请信息即可
- 列表样式可根据需求自行调整,比如添加在线标识、hover高亮效果等
内容的提问来源于stack exchange,提问作者Ryan143
相关产品推荐
相关产品推荐

