在meteor中,pub / sub可以用于任意的内存中对象(不是mongo集合)

时间:2014-10-19 22:03:21

标签: javascript mongodb meteor

我想在我的流星应用程序中建立双向(双向)通信。但是我需要在不使用mongo集合的情况下完成它。

那么pub / sub可以用于任意的内存中对象吗?

是否有更好,更快或更低级别的方式?表现是我​​最关心的问题。

感谢。

3 个答案:

答案 0 :(得分:5)

是的,pub / sub可用于任意对象。 Meteor’s docs even provide an example

// server: publish the current size of a collection
Meteor.publish("counts-by-room", function (roomId) {
  var self = this;
  check(roomId, String);
  var count = 0;
  var initializing = true;

  // observeChanges only returns after the initial `added` callbacks
  // have run. Until then, we don't want to send a lot of
  // `self.changed()` messages - hence tracking the
  // `initializing` state.
  var handle = Messages.find({roomId: roomId}).observeChanges({
    added: function (id) {
      count++;
      if (!initializing)
        self.changed("counts", roomId, {count: count});
    },
    removed: function (id) {
      count--;
      self.changed("counts", roomId, {count: count});
    }
    // don't care about changed
  });

  // Instead, we'll send one `self.added()` message right after
  // observeChanges has returned, and mark the subscription as
  // ready.
  initializing = false;
  self.added("counts", roomId, {count: count});
  self.ready();

  // Stop observing the cursor when client unsubs.
  // Stopping a subscription automatically takes
  // care of sending the client any removed messages.
  self.onStop(function () {
    handle.stop();
  });
});

// client: declare collection to hold count object
Counts = new Mongo.Collection("counts");

// client: subscribe to the count for the current room
Tracker.autorun(function () {
  Meteor.subscribe("counts-by-room", Session.get("roomId"));
});

// client: use the new collection
console.log("Current room has " +
            Counts.findOne(Session.get("roomId")).count +
            " messages.");

在此示例中,counts-by-room发布了从Messages.find()返回的数据创建的任意对象,但您可以轻松地将源数据放在其他位置并以相同方式发布。您只需提供与此处示例相同的addedremoved回调。

你会注意到在客户端上有一个名为counts的集合,但这纯粹是在客户端内存中;它没有保存在MongoDB中。我认为这是使用pub / sub。

的必要条件

如果您想避免使用仅限内存的集合,则应该查看Meteor.call。您可以创建一个Meteor.method,如getCountsByRoom(roomId),并从客户端调用它Meteor.call('getCountsByRoom', 123),该方法将在服务器上执行并返回其响应。这更像是传统的Ajax做事方式,而且你失去了Meteor的所有反应。

答案 1 :(得分:4)

只是添加另一个简单的解决方案。您可以将connection: null传递到服务器上的Collection实例。虽然这没有详细记录,但我从流星人那里听说这使得这个集合在内存中。

以下是Emily Stark一年前发布的示例代码:

if (Meteor.isClient) {
  Test = new Meteor.Collection("test");
  Meteor.subscribe("testsub");
}

if (Meteor.isServer) {
  Test = new Meteor.Collection("test", { connection: null });
  Meteor.publish("testsub", function () {
    return Test.find();
  });

  Test.insert({ foo: "bar" });
  Test.insert({ foo: "baz" });
}

答案 2 :(得分:0)

修改

这应该受到评论,但我发现它可能太长了所以我发布作为答案。或许我误解了你的问题?

我想知道你为何反对 mongo 。我不知何故觉得它与Meteor相匹配。

无论如何,每个人的用例都可能不同,你的想法是可行的,但不是一些严重的黑客攻击。

如果您查看Meteor源代码,您可以找到tools/run-mongo.js Meteor mongo 对话,您可以调整或实施适配器用于处理内存中的对象。

我能想到的另一种方法是封装你的内存中对象并编写一个数据库逻辑/层来拦截现有的 mongo 数据库通信(27017上的默认端口),你必须采取关注所有系统环境变量,如MONGO_URL等,以使其正常工作。

最终方法是等到 Meteor 正式支持 Redis 等其他数据库。

希望这有帮助。