问题
I have a publication on the meteor server and I would like to know how many clients are currently subscribed to that publication. The reason for this is, that I would like to show subscription count to a "publication owner".
Here is a simplified code-snipped of how I try to achieve this (of course instead of doing a console.log I would increment/decrement a shared document)
Meteor.publish('sessionForId', function (sessionId) {
console.log('increment subscription count for ' + sessionId);
this.onStop(function(){
console.log('decrement subscription count for ' + sessionId);
});
return Sessions.find({_id: sessionId});
});
In general this works, but there are some problems:
- If I restart the server, then the subscription count is out of sync (no onStop-Events are fired when stopping/killing/restarting the server)
- There are probably some other edge cases that can get the subscription count out of sync
I could probably work around some of these by i.e. setting the count to 0 on startup, but maybe there is a better way to query the server for the current amount of subscriptions to a publication?
回答1:
I didn't see anything in the docs how to do it better than your idea.
There's another possible approach shown below which iterates over these subscription objects : https://github.com/meteor/meteor/blob/devel/packages/ddp-server/livedata_server.js#L241
You can try it by putting the below code in your Server meteor code.
Meteor.setInterval(function(){
var output = {};
var connections = Meteor.server.stream_server.open_sockets;
_.each(connections,function(connection){
// named subscriptions
var subs = connection._meteorSession._namedSubs;
for(var sub in subs){
var mySubName = subs[sub]._name;
if(subs[sub]._params.length>0){
mySubName += subs[sub]._params[0]; // assume one id parameter for now
}
if(!output[mySubName]){
output[mySubName] = 1;
}else{
output[mySubName] += 1;
}
}
// there are also these 'universal subscriptions'
//not sure what these are, i count none in my tests
var usubs = connection._meteorSession._universalSubs;
});
console.log(output);
},2000);
This will output to the console the number of subscriptions per 'unique' publication every 2 seconds. A 'unique' publication would look like "Sessions1234", where "Sessions" is the name of the collection and "1234" was the id passed in by the subscriber. You could structure this however you want, I just made each 'unique' publication name into a string.
FWIW here's a meteor pad. But meteor pad runs a separate server per app session, so you're not going to see multiple subscribers if you open up more tabs. But you can at least get an idea of how it's working : http://meteorpad.com/pad/tYr4SE73QJA8ciw6p/Count%20Subscribers
I think if you just want to track that one publication your idea is pretty good. If you had tons of collections and wanted some analytics about connected clients and things, maybe the above approach is useful. since it's not part of the official meteor API probably prone to breaking on meteor version changes. The example uses setInterval just for illustrating the output easier, this should only be run when its needed if used.
来源:https://stackoverflow.com/questions/30800136/how-to-count-the-current-number-of-subscriptions-to-a-meteor-publication