按需发布流星?

时间:2015-06-18 20:13:34

标签: meteor publish-subscribe

有没有办法只在需要时向集合发布更新? (例如,每5秒仅发送一次更新?)

我正在发布一个排行榜,其中显示了游戏中前50名玩家(得分最多)。用户点的更新经常发生,因此排行榜经常变化(每1-5秒)。每分钟左右,服务器在forEach循环中为~100个用户更新点数。问题是发布方法在更新所有100个元素之前立即开始更新。这会产生一个痛苦的性能问题(多次向所有用户发布更新)......

在完成所有更新之前,有没有办法保留发布?或者只是每隔5秒而不是立即更新已发布数据的方法?

感谢您的帮助! :)

2 个答案:

答案 0 :(得分:1)

创建自定义发布并控制!

var pubsHandlers = [];

Meteor.publish('totalScore', function() {
  this.added('someClientCollection', 'totalScoreId', {
    totalScore : someGetTotalScoreFunction()
  });
  pubsHandlers.push(this); //Maaaaybe not the cleanest thing to do.
  this.ready();
});

Meteor.setInterval(function updateScores() {
  var newTotalScore = somegetTotalScoreFunction()
  pubsHandlers.forEach(function(pubHandler) {
    pubHandler.changed('someClientCollection', 'totalScoreId', {
      totalScore : newTotalScore
  });
}, 5000); //Each 5 seconds, update everyone

所以这就是发生的事情:

  1. 以自定义方式发布,adding将文档发布到我们的出版物
  2. 记住发布处理程序以进行进一步更新,
  3. 稍后(在interval中),使用记住的处理程序update文档。
  4. 主要好处是让服务器完全控制出版物及其更新 主要缺点是使用push(this)。它不一定很糟糕,但它看起来真可恶......

答案 1 :(得分:0)

文章http://tomkelsey.co.uk/reining-in-the-reactivity-with-meteor/讨论了这个确切的问题,作者使用了Meteor方法和通常的发布/订阅方法的组合。一个简化的例子如下所示。

在主页的onCreated方法中,我从服务器请求一个排序的项目_id数组,并将它们保存到名为itemIds的会话变量中:

Meteor.call('getItemIds', function(err, res) {   
   Session.set('itemIds', res);
});

在服务器上,该方法定义为:

Meteor.methods({
   getItemIds: function() {
    return Items.find({}, {fields: {_id: 1}, sort: 
    {rank:1}}).fetch();
  }
});

然后我监视itemIds会话变量的任何更改并相应地(重新)订阅:

var self = this;
self.autorun(function() {
    self.subscribe('itemsById', Session.get('itemIds'));
});

在服务器上,出版物如下所示:

Meteor.publish('itemsById', function(itemIds) {
    return Items.find({}, {_id: {$in: itemIds}});
});

我的模板遍历itemIds数组而不是Items集合游标。这意味着项目的顺序保持不变。

对于itemIds中的每个_id,我可以执行Items.find(_id) - 数据将在我们的客户端Items集合中,由我们的itemsById订阅提供。

Voila我们有一个反应项列表,在页面刷新之前将保留其订单。"

声音可以适合你:)