【问题标题】:Server cleanup after a client disconnects客户端断开连接后的服务器清理
【发布时间】:2012-05-02 17:33:14
【问题描述】:

有没有办法通过刷新或导航离开页面来检测客户端何时与流星服务器断开连接,以便服务器可以尝试进行一些清理?

【问题讨论】:

    标签: javascript meteor


    【解决方案1】:

    一种技术是实现每个客户端定期调用的“keepalive”方法。这假设您在每个客户的Session 中都有一个user_id

    // 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);
    

    【讨论】:

    • 经过大量搜索,我认为这是目前最好的解决方案。谢谢!!
    • 这几乎是伪代码,因为它不能正常工作:第一个 setInterval 没有指定间隔。 Connections.update 命令也没有指定更新 {'user_id':user_id}。可能还有其他错误。不过,这是一个好的开始。
    • @debergalis 这仍然是查看客户是否死亡的推荐方法吗?
    • @debergalis 我想知道你是否仍然推荐这种方法
    【解决方案2】:

    如果您使用 Auth,您可以在 Method 和 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});
    });
    

    【讨论】:

      【解决方案3】:

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

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

      更新:

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

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

      【讨论】:

      • 太好了。但后来我显然遇到了这个问题:stackoverflow.com/questions/10192938/…
      • 谢谢。这是我的问题的答案:Meteor observe running forever
      • 我使用流星 0.6.1 并且对于这一行 this.session.socket.on("close", function() { /*do your thing*/}); 我的服务器返回 TypeError: Cannot read property 'socket' of undefined 但是当我将其更正为 this._session.socket.on("close", function() { /*do your thing*/});效果很好,谢谢
      • 遗憾的是,在 0.6.3.1 中它不是 100% 可靠的。
      • 为什么 Meteor 文档没有说明这个或套接字?我找不到任何提及 _session 变量或套接字的内容?
      【解决方案4】:

      我已经实现了一个 Meteor 智能包,它可以跟踪来自不同会话的所有连接会话,并检测会话注销和断开连接事件,而无需昂贵的保活。

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

      要检测断开/注销事件,您只需执行以下操作:

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

      您也可以被动地使用它。看看吧!

      编辑: v0.3.0 of user-status 现在也跟踪处于空闲状态的用户!

      【讨论】:

      • 这可以在每页的基础上完成,而不是通过整个应用程序完成吗?
      • 是的,虽然这还没有实现。打开功能请求!
      【解决方案5】:

      我正在使用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!');
          }
      });
      

      【讨论】:

        猜你喜欢
        • 2012-10-02
        • 1970-01-01
        • 2016-07-26
        • 1970-01-01
        • 1970-01-01
        • 2015-05-17
        • 2016-05-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多