I'm trying to implement my own custom ping-pong for my meteor application (meteor has a ping-pong implemented for internal use, but I want to introduce a custom behavior). The only way that I found to send data to a client was by using a publisher, so I set a setInterval
, to send a new payload with the timestamp of the pong, but in each new subscription is created a new setInterval
. How could I set just a one publish or setInterval? Or there some another way to send a message to client?
const COLLECTION_NAME = 'ping-pong';
const POLL_INTERVAL = 5000;
function pingPong(credentials) {
const pongSender = () => {
const id = _.uniqueId('pong-');
const payload = {
message: 'pong',
time: Date.now(),
};
this.added(COLLECTION_NAME, id, payload);
};
pongSender();
this.ready();
const interval = Meteor.setInterval(pongSender, POLL_INTERVAL);
this.onStop(() => {
Meteor.clearInterval(interval);
});
}
Each publication is handled separately, but you can create only one interval and let it update a list of publication handles:
const pingPongSubscribed = [];
const pingPongIntervalId = setInterval(() => {
pingPongSubscribed.forEach(handle => {
// ...
handle.added(COLLECTION_NAME, DOCUMENT_ID, payload);
});
}, 5000);
// ...
Meteor.publish('example', function () {
// ...
pingPongSubscribed.push(this);
this.onStop(() => {
pingPongSubscribed.splice(pingPongSubscribed.indexOf(this), 1);
});
});
If you need more data, simply keep it in the pingPongSubscribed
. Keep in mind, that it will be synchronized in terms of connection to one server and multiple server instances are not synchronized.
Also, consider using changed
instead. Each use of added
is creating a new document in the server and client memory. This way you'll manage only one document and react to changes accordingly.