最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - In meteor, can pubsub be used for arbitrary in-memory objects (not mongo collection) - Stack Overflow

programmeradmin1浏览0评论

I want to establish a two-way (bidirectional) munication within my meteor app. But I need to do it without using mongo collections.

So can pub/sub be used for arbitrary in-memory objects?

Is there a better, faster, or lower-level way? Performance is my top concern.

Thanks.

I want to establish a two-way (bidirectional) munication within my meteor app. But I need to do it without using mongo collections.

So can pub/sub be used for arbitrary in-memory objects?

Is there a better, faster, or lower-level way? Performance is my top concern.

Thanks.

Share Improve this question asked Oct 19, 2014 at 22:03 DaveDave 12.5k10 gold badges48 silver badges52 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

Yes, pub/sub can be used for arbitrary objects. 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.");

In this example, counts-by-room is publishing an arbitrary object created from data returned from Messages.find(), but you could just as easily get your source data elsewhere and publish it in the same way. You just need to provide the same added and removed callbacks like the example here.

You’ll notice that on the client there’s a collection called counts, but this is purely in-memory on the client; it’s not saved in MongoDB. I think this is necessary to use pub/sub.

If you want to avoid even an in-memory-only collection, you should look at Meteor.call. You could create a Meteor.method like getCountsByRoom(roomId) and call it from the client like Meteor.call('getCountsByRoom', 123) and the method will execute on the server and return its response. This is more the traditional Ajax way of doing things, and you lose all of Meteor’s reactivity.

Just to add another easy solution. You can pass connection: null to your Collection instantiation on your server. Even though this is not well-documented, but I heard from the meteor folks that this makes the collection in-memory.

Here's an example code posted by Emily Stark a year ago:

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

Edit

This should go under ment but I found it could be too long for it so I post as an answer. Or perhaps I misunderstood your question?

I wonder why you are against mongo. I somehow find it a good match with Meteor.

Anyway, everyone's use case can be different and your idea is doable but not with some serious hacks.

if you look at Meteor source code, you can find tools/run-mongo.js, it's where Meteor talks to mongo, you may tweak or implement your adaptor to work with your in-memory objects.

Another approach I can think of, will be to wrap your in-memory objects and write a database logic/layer to intercept existing mongo database munications (default port on 27017), you have to take care of all system environment variables like MONGO_URL etc. to make it work properly.

Final approach is wait until Meteor officially supports other databases like Redis.

Hope this helps.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论