0

我在我的 Rails 应用程序上使用 socket.io 在数据库上在线/离线服务器用户,我使用 Redis 存储数据,0 用于离线,1 用于我的 app.js 文件的在线状态

var app = require('express')()
, redis = require('redis')
, client = redis.createClient()
, server = require('http').createServer(app)
, io = require('socket.io').listen(server);

server.listen(80);

io.sockets.on('connection', function (socket) {
console.log("client connected")


socket.on('join',function(userid){
socket.set('userid',userid);

var utm ="user:"+userid+":online_status";
client.set(utm,1);

});
socket.on('disconnect',function(userid){
socket.get('userid',function(err,userid){
var utm ="user:"+userid+":online_status";
client.set(utm,0);
});
});
});

在我的 application.html 布局中,我的 application.js 文件中已经包含了 socket.io.js 并且它运行良好



    var socket = io.connect('http://localhost:80');

     socket.on('connect',function(data){
      var userID = current_user.id;
      socket.emit('join',userID);

     });

除了当用户同时打开两个窗口时,一切都工作正常,如果他关闭一个窗口断开事件触发并且他的状态变为离线,我怎样才能使断开事件仅在用户关闭所有窗口时才起作用而不是一个?

4

1 回答 1

1

代替二进制文件来存储状态,也许使用连接计数器。连接时递增,断开时递减。当它为 0 时,用户已关闭所有窗口。

您还可以考虑这些计数器的过期时间,以防用户以阻止断开连接事件触发的方式消失(例如浏览器崩溃、网络断开连接等)。

这段代码是近似的,但试试看:

socket.on('join',function(userid){
    socket.set('userid',userid);
    var utm ="user:"+userid+":online_status";
    client.incr(utm);
});

socket.on('disconnect',function(userid){
  socket.get('userid',function(err,userid){
    var utm ="user:"+userid+":online_status";
    client.decr(utm);
  });
});
于 2013-03-02T01:40:52.103 回答