Очистка сервера после отсоединения клиента

Есть ли способ обнаружить, когда клиент отключается от метеоритного сервера, либо обновляясь, либо перемещаясь от страницы, чтобы сервер мог выполнить некоторую очистку?

Ответ 1

Один из способов - реализовать метод "keepalive", который каждый клиент регулярно вызывает. Предполагается, что у вас есть 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);

Ответ 2

Я думаю, что лучший способ - уловить событие закрытия сокета в функции публикации.

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

Ответ 3

Я реализовал интеллектуальный пакет Meteor, который отслеживает все подключенные сеансы из разных сеансов и обнаруживает как выход из системы, так и отключает события без дорогостоящего keepalive.

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

Чтобы обнаружить события отключения/выхода из системы, вы можете просто сделать следующее:

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

Вы также можете использовать его реактивно. Проверьте это!

EDIT: v0.3.0 статуса пользователя теперь также отслеживает простаивание пользователей!

Ответ 4

Если вы используете Auth, у вас есть доступ к идентификатору пользователя в функции "Метод" и "Опубликовать", вы можете реализовать свое отслеживание там, например. вы можете установить "последний раз", когда пользователь переключает комнату:

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

Ответ 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!');
    }
});