如何使用socket.io确定浏览器何时完全断开与我的站点的连接?

时间:2016-10-05 15:37:07

标签: node.js socket.io

因为人们可以打开许多标签并使用许多浏览器,所以我在确定用户何时关闭每个浏览器的所有标签时遇到了一些麻烦。

2 个答案:

答案 0 :(得分:-1)

如果所有标签都已关闭,则用户不再连接,因此我假设您想知道服务器上是否完全断开连接?

您应该在服务器上保存一个针对用户标识符(登录名或类似名称)的套接字列表,当打开一个新标签时,它将有一个新的套接字连接,因此将其添加到列表中。

关闭套接字连接后,将其从该用户的套接字集合中删除。

当用户的最后一个套接字连接关闭时,您知道用户已完全断开连接。

使用示例编辑

像这样的东西(未经测试和匆匆写的!)

'use strict';

var userConnections = [];

io.on('connection', function (socket) {

  var username = socket.request.user.username;

  var existingUser = userConnections.find(function(userConnection){
    return userConnection.username === username;
  })

  if (!existingUser){
    existingUser = { 
      username: username,
      sockets: []
     }
  }

  existingUser.sockets.push(socket);

  socket.on('disconnect', function () {

    var socketIndex = existingUser.indexOf(socket);
    existingUser.sockets.splice(socketIndex, 1);

    if (existingUser.sockets.length === 0){
      //user has completely disconnected
    } 

  });
});

编辑 - 澄清后(见评论)

OP表示他希望了解特定浏览器实例的所有连接何时断开连接。

由于您无法从javascript访问有关浏览器进程的任何系统信息,因此我看不到任何实现此目的的方法。

可以检测客户端上的浏览器类型(Chrome / IE / Edge等),并在套接字连接上发送此信息。然后,您可以存储引用此信息的套接字信息。但是我认为这不是OP想要的。

答案 1 :(得分:-1)

这是我的解决方案,它取决于@Banners的一个。 " socket.cookies"存储浏览器的cookie 如果我遗失了什么,请现在就告诉我。

'use strict';

var userConnections = {};

io.on('connection', function (socket) {

  var username = socket.request.user.username;
  var visit_id = (socket.cookies.vid) ? socket.cookies.vid : random_unique_id();

  //set cookie here
  setCookie('vid', visit_id, expire);

  if (!userConnections[visit_id])
    userConnections[visit_id] = [];

  userConnections[visit_id].push(socket.id);

  socket.on('disconnect', function () {

    var vid = socket.cookies.vid;

    if (userConnections[vid]) {
        var index = userConnections[vid].indexOf(socket.id);
        if (index != -1)
            userConnections[vid].splice(index, 1);

        if (userConnections[vid].length === 0) {
            delete userConnections[vid];
            //All tabs have been closed
        }
    }

  });
});