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

如何从客户端JS文件访问Server.js中的online_users全局变量

实现客户端获取并展示Socket.io在线用户列表

问题背景

我有一个Server.js文件,会将所有连接到服务器的客户端Socket ID添加到online_users列表中;另有一个客户端JavaScript文件,其中的showOnline方法会在点击“多人”按钮时触发模态框。我希望从该客户端JS文件中访问Server.js里的online_users列表,将在线用户列表展示在小型模态框内。

当前代码

Server.js

io.on('connection', (socket) => {
    console.log('user with ' + socket.id + ' connected');
    // 将socket id添加到服务器的在线用户列表
    online_users.push(socket.id);
    
    socket.on('joinRoom', (room) => {
        socket.join(room);
        console.log(`User joined room: ${room}`);
    });

    socket.on('move', (data) => {
        const { room, message } = data;
        io.to(room).emit('move', message);
    });

    socket.on('disconnect', () => {
        console.log('user disconnected');
        // 从online_users列表中移除客户端(此处代码未完成)
        online_users.wh
    });
});

客户端JavaScript

// 展示在线用户的方法
// 应该每秒调用一次以获取实时更新
function showOnline() {
    // 从server.js暴露的全局变量中获取在线列表
    
    // 程序化创建新表格,左侧显示头像,右侧显示用户的socket id
    $('#onlineModal').modal('show');
}

解决方案

1. 完善服务器端的用户移除逻辑

首先补全disconnect事件中的代码,确保用户断开连接时从列表中移除:

socket.on('disconnect', () => {
    console.log('user disconnected');
    // 找到socket id在列表中的索引并移除
    const index = online_users.indexOf(socket.id);
    if (index !== -1) {
        online_users.splice(index, 1);
    }
});

2. 服务器端添加在线列表交互逻辑

有两种常见实现方式:

方式一:客户端主动请求在线列表

在Server.js中添加监听客户端请求的事件:

io.on('connection', (socket) => {
    // ... 原有代码 ...
    
    // 监听客户端获取在线列表的请求
    socket.on('getOnlineUsers', () => {
        socket.emit('onlineUsers', online_users);
    });
});

方式二:服务器主动推送在线列表更新

当用户上线或下线时,主动把更新后的列表推送给所有客户端:

io.on('connection', (socket) => {
    console.log('user with ' + socket.id + ' connected');
    online_users.push(socket.id);
    // 用户上线时推送更新后的列表
    io.emit('onlineUsersUpdate', online_users);
    
    // ... 原有代码 ...
    
    socket.on('disconnect', () => {
        console.log('user disconnected');
        const index = online_users.indexOf(socket.id);
        if (index !== -1) {
            online_users.splice(index, 1);
        }
        // 用户下线时推送更新后的列表
        io.emit('onlineUsersUpdate', online_users);
    });
});

3. 客户端修改showOnline方法渲染列表

根据选择的方式修改客户端代码:

对应方式一(主动请求):

function showOnline() {
    // 向服务器请求在线用户列表
    socket.emit('getOnlineUsers');
    // 监听服务器返回的在线列表并渲染
    socket.on('onlineUsers', (users) => {
        renderOnlineUsers(users);
    });
    $('#onlineModal').modal('show');
}

// 渲染在线用户表格的函数
function renderOnlineUsers(users) {
    const table = $('<table class="table table-sm"></table>');
    // 添加表头
    table.append('<thead><tr><th>头像</th><th>Socket ID</th></tr></thead>');
    const tbody = $('<tbody></tbody>');
    // 遍历用户列表生成行
    users.forEach(userId => {
        const row = $('<tr></tr>');
        // 用文字标签代替头像,可替换为图片
        row.append('<td><span class="badge bg-primary">头像</span></td>');
        row.append(`<td>${userId}</td>`);
        tbody.append(row);
    });
    table.append(tbody);
    // 清空模态框内容并插入表格
    $('#onlineModal .modal-body').empty().append(table);
}

对应方式二(主动推送):

// 提前监听服务器推送的在线列表更新,缓存最新数据
let currentOnlineUsers = [];
socket.on('onlineUsersUpdate', (users) => {
    currentOnlineUsers = users;
});

function showOnline() {
    // 直接用缓存的在线列表渲染
    renderOnlineUsers(currentOnlineUsers);
    $('#onlineModal').modal('show');
}

// 渲染函数同上
function renderOnlineUsers(users) {
    const table = $('<table class="table table-sm"></table>');
    table.append('<thead><tr><th>头像</th><th>Socket ID</th></tr></thead>');
    const tbody = $('<tbody></tbody>');
    users.forEach(userId => {
        const row = $('<tr></tr>');
        row.append('<td><span class="badge bg-primary">头像</span></td>');
        row.append(`<td>${userId}</td>`);
        tbody.append(row);
    });
    table.append(tbody);
    $('#onlineModal .modal-body').empty().append(table);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 01:53:14