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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 06:06:06