求助类似qq异地登陆,后一个登陆者挤掉前一个登陆者?

1.就是同一个帐号,在网页上登陆,后面的登陆者挤掉前面的登陆者,并且提示 此账号已经在其他地方登陆,然后退出去! 谢谢

阅读 7.8k
7 个回答

我们没用楼上说的ajax的轮询,而是用websocket,保持一个长链接。socket.io的实现。

每次用户连接上来,缓存他的登录信息,比如:uid、session、token、socketID的信息,然后,每一次下线(长链接断掉)就删掉相关的记录。

然后在他连接的时候根据他的uid和socketID来查找是否已经登录过了,从而执行相关的踢人逻辑,用之前存好的socketID,找到相应的socket,发送‘你被挤下线’的消息。
之所以要匹配socketID,因为有时候网络不稳定等因素,socket可以直接重连。

在系统中通过用户ID 与 session_id 维护一个关联, 再次登录时,把用户ID关联指向第二次用户登陆的session_id,并在第一次session添加一个异地登陆的标识

// 第一次登陆
session_id1  ==> {user:{用户信息}}
user_id      ==>  session_id1
// 第二次登陆
session_id2  ==> {user:{用户信息}}
user_id      ==>  session_id1
session_id1  ==> {user:{用户信息},other_login: true} // 第一次登陆用户刷新页面时提示异地登陆

记录用户 session 就好的。
用网页的 session_id 作为网页的标识,在服务器记录用户当前的 session_id, 后登陆的替换这个 session_id, 之前的 session_id 查询服务器的时候发现 session_id 直接退出。

1.登录后,记录session_id存到数据库,界面ajax实时获取,判断是否是登录状态

2.后者登录时,把之前保存的session_id,赋值给自己,由于session是绑定浏览器cookies的,所以只要你把sessionid绑定到后者登录的服务器,前者自然就没有登录的session,比方说session里面的用户名,用户ID什么的都是空的,即为登出状态。

clipboard.png

有个简单的做法,登陆时,把本次登陆时间分别存到session和用户表里。每次操作前判断或用ajax定时获取,两个时间不一致就提示有其他登陆并退出。

  socket.on('login',function(userobj){
        socket.name = userobj.temporaryId;   //用来disconnect的时候使用
        userobj.socketid = socket.id;
        var beforeSocketid = hadInUserList(userobj.userid);
        if(beforeSocketid){
            var disconnectSocket = server.sockets.sockets[beforeSocketid];
            disconnectSocket.emit('forceDisconnect'); //通知下线
        }
        onlineUserCount++;
        onlineUsers[userobj.temporaryId] = {userid:userobj.userid,username:userobj.username,socketid:socket.id};
        server.emit('login',{onlineUserCount:onlineUserCount,onlineUsers:onlineUsers,userobj:userobj});
        console.log(userobj.username + ' joined chat')
    });

分享一下我自己用nodejs socket.io写的一段吧。实际的代码,你可以当做伪代码看。客户端那边的操作就是断开链接弹出被挤下去的提示

这个很简单,用户表里面存放一个 字段 last_login 登录成功随机生成一个值,分别存放到 session 和 这个字段里面,然后判断当前 session 里面的和 表里面的 last_login 字段是否匹配,不匹配则系统默认退出当前用户的登录状态

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏