socket.io 判断用户是在线还是离线

Posted

技术标签:

【中文标题】socket.io 判断用户是在线还是离线【英文标题】:socket.io determine if a user is online or offline 【发布时间】:2015-11-15 01:29:45 【问题描述】:

我们可以通过这段代码来追踪连接是建立还是断开

console.log('a user connected');
    socket.on('disconnect', function () 
        console.log('user disconnected');
    );

嗯,没关系。但是我们如何确定哪些用户连接或离线。我的客户是用php/html写的,所以他们有一个用户ID。

【问题讨论】:

我不确定你的问题。你想让客户端检查其他客户端是否在线吗?或者你想让服务器确定连接的客户端是什么? 【参考方案1】:

如果您的客户端有特定的用户 ID,他们需要将它们发送到 socket.io 服务器。例如。在客户端你可以做

<script>
 const socket = io();
 socket.emit('login',userId:'YourUserID');
</script>

在服务器上你会放一些类似的东西

const users = ;
io.on('connection', function(socket)
  console.log('a user connected');

  socket.on('login', function(data)
    console.log('a user ' + data.userId + ' connected');
    // saving userId to object with socket ID
    users[socket.id] = data.userId;
  );

  socket.on('disconnect', function()
    console.log('user ' + users[socket.id] + ' disconnected');
    // remove saved socket from users object
    delete users[socket.id];
  );
);

现在您可以将套接字 ID 与您的用户 ID 配对并使用它。

【讨论】:

当用户断开连接时,您不应该从用户数组中删除用户吗? 然而,每当客户端浏览器刷新时,socket id 就会改变。所以我的问题是您是否需要在每个套接字 id 更改时添加它以保持在线状态? 这是个好问题。如果您只是在断开连接事件时从用户对象中删除 socket.id 键,用户将在重新连接到服务器时创建新的 socket.id 并将他的 userId 保存在那里。 好的,我对此还有其他问题。如果我想在每次断开连接时删除数组中用户的套接字条目,那么如何在代码中做到这一点? @galethil 当我打开多个选项卡时,每个新选项卡都会为同一用户创建新的套接字 ID,我认为您需要管理特定用户的套接字 ID 数组。【参考方案2】:

除了@galethil 的回答,如果用户打开多个选项卡(套接字连接),每个选项卡(套接字连接) 对单个用户都有唯一的套接字ID 怎么办? ,所以我们需要管理特定用户的套接字 id 数组,

客户端连接: 支持Socket IO Client v3.x,

<!-- SOCKET LIBRARY IN HTML -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.0.5/socket.io.js"></script>
const host = "http://yourdomain.com";
// PASS your query parameters
const queryParams =  userId: 123 ;
const socket = io(host, 
    path: "/pathToConnection",
    transports: ['websocket'],  // https://***.com/a/52180905/8987128
    upgrade: false,
    query: queryParams,
    reconnection: false,
    rejectUnauthorized: false
);

socket.once("connect", () => 
    
    // USER IS ONLINE
    socket.on("online", (userId) => 
        console.log(userId, "Is Online!"); // update online status
    );

    // USER IS OFFLINE
    socket.on("offline", (userId) => 
        console.log(userId, "Is Offline!"); // update offline status
    );

);

服务器端连接:支持Socket IO Server v3.x,

依赖关系:
const _ = require("lodash");
const express = require('express');
const app = express();
const port = 3000; // define your port
const server = app.listen(port, () => 
  console.log(`We are Listening on port $port...`);
);
连接:
const io = require('socket.io')(server, 
    path: "/pathToConnection"
);
let users = ;
io.on('connection', (socket) => 

  let userId = socket.handshake.query.userId; // GET USER ID
  
  // CHECK IS USER EXHIST 
  if (!users[userId]) users[userId] = [];
  
  // PUSH SOCKET ID FOR PARTICULAR USER ID
  users[userId].push(socket.id);
   
  // USER IS ONLINE BROAD CAST TO ALL CONNECTED USERS
  io.sockets.emit("online", userId);

  // DISCONNECT EVENT
  socket.on('disconnect', (reason) => 

    // REMOVE FROM SOCKET USERS
    _.remove(users[userId], (u) => u === socket.id);
    if (users[userId].length === 0) 
      // ISER IS OFFLINE BROAD CAST TO ALL CONNECTED USERS
      io.sockets.emit("offline", userId);
      // REMOVE OBJECT
      delete users[userId];
    
   
    socket.disconnect(); // DISCONNECT SOCKET

  );

);

GitHub Demo

【讨论】:

您好,我测试了您所说的,似乎打开一个新选项卡并没有创建一个新的套接字 id。也许 socket.io 最近发生了一些变化? 我已经对其进行了测试,直到版本 3 可以正常工作,我不确定以上版本,您使用的是什么版本? 啊,是的,我使用的是 4.0.1 版。没有意识到。我以为我们还在第 3 版哈哈。无论如何,版本 4 似乎不是这种情况。ID 现在保持一致。 我已经在 4.0.1 版本中测试了它与 3.0 版本相同的功能,我认为你做错了什么。您可以按照随附的 github 演示,只需将 socket.io npm 更新为最新并在 index.html 文件中更新最新版本。 嗨,你是对的。我犯了一个错误。感谢您的帮助!【参考方案3】:

我们可以识别服务器中的socket id,谁是连接的,谁是断开的。所以你可以做这样的事情。如果您在客户端有标识符,则可以使用此设置

客户

socket.emit('login', userId);

服务器端

const users = ;
io.on("connection", (socket) => 

   socket.on("login", (data) => 
      users[socket.id] = data;
    );

  socket.on("disconnecting", (reason) => 
    
    delete users[socket.id]; // remove the user. -- maybe not the exact code
  );
);

希望你能明白。

【讨论】:

以上是关于socket.io 判断用户是在线还是离线的主要内容,如果未能解决你的问题,请参考以下文章

当接收器离线时,socket.io 发出不工作

处理 Socket.io 中的服务器故障

Socket.io 私信,多用户同时在线

使用 Redis 和 Socket.io 进行用户认证

socket.io如何进行分布式部署

vue + socket.io实现一个简易聊天室