In meteor, you can use pub / sub for arbitrary objects in memory (rather than a mongo collection)

I want to set a two-way (bi-directional) message in my meteor application. But I need to do this without using the mongo collections.

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

Is there a better, faster, or lower level? Performance is my main concern.

Thanks.

+5
source share
3 answers

Yes, pub / sub can be used for arbitrary objects. Meteors 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 publishes an arbitrary object created from the data returned from Messages.find() , but you can also easily get the original data elsewhere and publish it in the same way. You just need to provide the same added and removed callbacks as here.

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

If you want to avoid even collections in memory, you should look at Meteor.call . You can create Meteor.method as getCountsByRoom(roomId) and call it on the client, for example Meteor.call('getCountsByRoom', 123) , and the method will execute on the server and return its response. This is more of a traditional Ajax way of doing things, and you lose all Meteors reactivity.

+5
source

Just add another simple solution. You can pass connection: null to the collection instance on your server. Despite the fact that this is not well documented, but I heard from meteor people that it does collecting in memory.

Here is 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" }); } 
+4
source

Edit

This should go under the comments, but I found that it could be too long for him, so I am posting as an answer. Or maybe I misunderstood your question?

I wonder why you are against mongo . I somehow think that this is a good match with Meter.

In any case, everyone uses a case that may be different, and your idea is feasible, but not with some serious hacks.

if you look at the source code of Meteor, you can find tools/run-mongo.js , where Meteor says mongo , you can configure or implement your adapter to work with your in-memory.

Another approach I can come up with is to wrap your objects in memory and write the database logic / level to intercept the existing connection to the mongo database (default port on 27017), you should take care of all the system environment variables, such as MONGO_URL etc. to make it work correctly.

The final approach waits until Meteor officially supports other databases, such as Redis .

Hope this helps.

0
source

Source: https://habr.com/ru/post/1205053/


All Articles