2012-04-21 57 views
20

有没有一种方式,当客户端从服务器流星断开检测,或者通过刷新或从页面导航离开,从而使服务器可以尝试一些清理工作?服务器断开清理

回答

18

一种技术是实现“保活”的方法,每个客户端调用定期。这假定你有一个user_id在每个客户的Session举行。

// server code: heartbeat method 
Meteor.methods({ 
    keepalive: function (user_id) { 
    if (!Connections.findOne(user_id)) 
     Connections.insert({user_id: user_id}); 

    Connections.update(user_id, {$set: {last_seen: (new Date()).getTime()}}); 
    } 
}); 

// server code: clean up dead clients after 60 seconds 
Meteor.setInterval(function() { 
    var now = (new Date()).getTime(); 
    Connections.find({last_seen: {$lt: (now - 60 * 1000)}}).forEach(function (user) { 
    // do something here for each idle user 
    }); 
}); 

// client code: ping heartbeat every 5 seconds 
Meteor.setInterval(function() { 
    Meteor.call('keepalive', Session.get('user_id')); 
}, 5000); 
+0

经过多次搜索,我认为这是现在的最佳解决方案。谢谢!! – greggreg 2012-04-24 05:38:19

+6

这几乎是伪代码,因为它不起作用:第一个setInterval没有指定间隔。 Connections.update命令也没有指定更新{'user_id':user_id}。可能还有其他错误。不过这是一个好的开始。 – 2012-09-08 16:53:05

+3

@debergalis这仍然是推荐的方式,看看客户是否已经死了? – user2602152 2014-01-19 12:46:09

1

如果您使用的是Auth,您可以在Method and Publish函数中访问用户的ID,那么您可以在那里实现您的跟踪。当用户切换房间时,你可以设置“最后看到”:

Meteor.publish("messages", function(roomId) { 
    // assuming ActiveConnections is where you're tracking user connection activity 
    ActiveConnections.update({ userId: this.userId() }, { 
     $set:{ lastSeen: new Date().getTime() } 
    }); 
    return Messages.find({ roomId: roomId}); 
}); 
13

我认为更好的方法是捕获发布函数中的套接字关闭事件。

Meteor.publish("your_collection", function() { 
    this.session.socket.on("close", function() { /*do your thing*/}); 
} 

UPDATE:

更新的版本流星的使用_session这样的:

this._session.socket.on("close", function() { /*do your thing*/}); 
+0

太棒了。但后来我显然遇到这个问题:http://stackoverflow.com/questions/10192938/meteor-code-must-always-run-within-a-fiber-when-calling-collection-insert-on-s – huyz 2012-09-28 08:53:23

+0

谢谢。这是回答我的问题:[流星观摩运行下去(http://stackoverflow.com/q/12902392/599991) – zVictor 2012-10-16 17:29:40

+3

我用流星0.6.1和此行'this.session.socket.on(”关闭“,函数(){/ *做你的事* /});'我的服务器返回_TypeError:无法读取undefined_的属性'套接字'但是当我纠正它'this._session.socket.on(”close“,函数(){/ *做你的事情* /});'它工作得很好,谢谢 – fantom 2013-04-13 18:04:26

2

我已经实现了一个流星智能包,跟踪从不同会话的所有连接的会话,并检测这两个会话注销并断开事件,而不需要昂贵的Keepalive。

https://github.com/mizzao/meteor-user-status

为了检测断开/注销事件,你可以做到以下几点:

UserStatus.on "connectionLogout", (info) -> 
    console.log(info.userId + " with session " + info.connectionId + " logged out") 

你也可以用它被动。一探究竟!

编辑:v0.3.0用户状态现在跟踪用户空闲以及!

+0

这可以在每个页面的基础上完成,而不是通过整个应用程序? – Scalahansolo 2014-06-26 15:56:26

+0

是的,虽然这还没有实施。打开功能请求! – 2014-06-26 15:57:33

-1

我使用Iron Router,并呼吁unload事件我的主控制器我清理代码。当然,这不会赶上标签关闭的事件,但仍然感觉很好用于许多用例

ApplicationController = RouteController.extend({ 
    layoutTemplate: 'root', 
    data: {}, 
    fastRender: true, 
    onBeforeAction: function() { 
     this.next(); 
    }, 
    unload: function() { 
     if(Meteor.userId()) 
      Meteor.call('CleanUpTheUsersTrash'); 
    }, 
    action: function() { 
     console.log('this should be overridden by our actual controllers!'); 
    } 
});