是否可以(使用Meteor)控制何时将发布推送到订阅的客户端?

时间:2014-02-02 20:07:00

标签: javascript meteor

使用Meteor进行编程时,是否可以控制何时将发布(DDP更新到本地MiniMongo)发送到订阅的客户端。看起来默认行为是在对关联集合进行任何更改后立即推送更改。在我的应用程序中,这将是非常低效的,并导致许多不必要的更新。

理想情况下,我想做的是推迟推送更改,直到我在另一个集合中进行特定更改。

因此,例如,如果我有以下集合以及相关的出版物和订阅:

// Client and server
Scores = new Meteor.Collection('scores');
GameState = new Meteor.Collection('gameState');

Meteor.publish('scores', function(gameId) {
    return Scores.find({id: gameId});
});

Meteor.publish('gameState', function(gameId) {
    return GameState.find({id: gameId});
});

// Client only
Meteor.subscribe('scores');
Meteor.subscribe('gameState');

我想做的是延迟更新客户的本地“分数”集合,直到游戏状态达到特定状态。

2 个答案:

答案 0 :(得分:1)

如果我正确理解了问题,您可以使用autorun和会话变量的组合来触发订阅。像这样:

Tracker.autorun(function() {
  var gameId = Session.get('currentGame');
  if (gameId && Session.get('excitingLevel')) {
    Meteor.subscribe('scores', gameId);
    Meteor.subscribe('gameState', gameId);
  }
});

我在这里使用excitingLevelcurrentGame(可能没有游戏进行?)来激活订阅。另请注意,如果不再符合条件,autorun足够聪明,可以停止订阅。因此,如果玩家离开游戏(Session.set('currentGame', undefined))或者等级不再令人兴奋,则订阅将结束。

其他说明

  • 如果游戏状态变化非常快,我可能值得评估streams,而不是使用游戏状态的集合。
  • 可能需要做某种load testing以确定哪种解决方案最佳。

答案 1 :(得分:0)

在服务器端代码发布scores或多或少像这样:

GameState = new Meteor.Collection('gameState')

/* Publish a custom Scores collection */
Meteor.publish("scores", function () {
  var self = this

  gameStateCursor = GameState.find();
  observerHandle = gameStateCursor.observe({
    added: function (document, index) {
      /* This is called whenever a new document is added to the game state. */

      if (/* gameState ready to publish to scores */)
        self.changed("scores", scoreId, scoreData)

      /* or use self.added() */
    },
    /* more functions as described in publish() */

  }
}

这不是一个完整的答案,而是一个粗略的轮廓。这个observe()框架非常强大,但是低级别。几乎一切皆有可能。我可以想象用observe()发布波数据的傅里叶变换,这就是这个疯狂的强大。

请仔细阅读https://docs.meteor.com/#meteor_publishhttps://docs.meteor.com/#publish_added及以下(添加,更改和删除)。