Server cleanup after a client disconnects

后端 未结 5 1558
花落未央
花落未央 2020-12-01 07:55

Is there a way to detect when a client disconnects from a meteor server, either by refreshing or navigating away from the page, so that the server can attempt some cleanup?<

相关标签:
5条回答
  • 2020-12-01 08:35

    One technique is to implement a "keepalive" method that each client regularly calls. This assumes you've got a user_id held in each client's 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 讨论(0)
  • 2020-12-01 08:37

    I'm using Iron Router and call my cleanup code on the unload event of my main controller. Sure this will not catch the event of a tab closing, but still feels good enough for many use cases

    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!');
        }
    });
    
    0 讨论(0)
  • 2020-12-01 08:40

    if you're using Auth you have access to the user's ID in Method and Publish functions, you could implement your tracking there.. e.g. you could set a "last seen" when the user switches room:

    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});
    });
    
    0 讨论(0)
  • 2020-12-01 08:44

    I think better way is to catch socket close event in publish function.

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

    UPDATE:

    Newer version of meteor uses _session like this:

    this._session.socket.on("close", function() { /*do your thing*/});
    
    0 讨论(0)
  • 2020-12-01 08:52

    I've implemented a Meteor smart package that tracks all connected sessions from different sessions and detects both session logout and disconnect events, without an expensive keepalive.

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

    To detect disconnect/logout events, you can just do the following:

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

    You can also use it reactively. Check it out!

    EDIT: v0.3.0 of user-status now tracks users being idle as well!

    0 讨论(0)
提交回复
热议问题