@sex-pomelo/sex-pomelo
Version:
[![NPM version][npm-image-pomelo]][npm-url-pomelo] [![NPM version][npm-image-down]][npm-url-pomelo]
118 lines (98 loc) • 2.88 kB
JavaScript
;
const utils = require('../util/utils');
const DEFAULT_FLUSH_INTERVAL = 20;
let ServiceBuffer = function(app, opts) {
if (!(this instanceof ServiceBuffer)) {
return new ServiceBuffer(app, opts);
}
opts = opts || {};
this.app = app;
this.flushInterval = opts.flushInterval || DEFAULT_FLUSH_INTERVAL;
this.sessions = {}; // sid -> msg queue
this.tid = null;
};
module.exports = ServiceBuffer;
ServiceBuffer.prototype.start = function(cb) {
this.tid = setInterval(flush.bind(null, this), this.flushInterval);
process.nextTick(function() {
utils.invokeCallback(cb);
});
};
ServiceBuffer.prototype.stop = function(force, cb) {
if(this.tid) {
clearInterval(this.tid);
this.tid = null;
}
process.nextTick(function() {
utils.invokeCallback(cb);
});
};
ServiceBuffer.prototype.schedule = function(reqId, route, msg, recvs, opts, cb) {
opts = opts || {};
if(opts.type === 'broadcast') {
doBroadcast(this, msg, opts.userOptions);
} else {
doBatchPush(this, msg, recvs);
}
process.nextTick(function() {
utils.invokeCallback(cb);
});
};
let doBroadcast = function(self, msg, opts) {
let channelService = self.app.get('channelService');
let sessionService = self.app.get('sessionService');
if(opts.binded) {
sessionService.forEachBindedSession(function(session) {
if(channelService.broadcastFilter &&
!channelService.broadcastFilter(session, msg, opts.filterParam)) {
return;
}
enqueue(self, session, msg);
});
} else {
sessionService.forEachSession(function(session) {
if(channelService.broadcastFilter &&
!channelService.broadcastFilter(session, msg, opts.filterParam)) {
return;
}
enqueue(self, session, msg);
});
}
};
let doBatchPush = function(self, msg, recvs) {
let sessionService = self.app.get('sessionService');
let session;
for(let i=0, l=recvs.length; i<l; i++) {
session = sessionService.get(recvs[i]);
if(session) {
enqueue(self, session, msg);
}
}
};
let enqueue = function(self, session, msg) {
let queue = self.sessions[session.id];
if(!queue) {
queue = self.sessions[session.id] = [];
session.once('closed', onClose.bind(null, self));
}
queue.push(msg);
};
let onClose = function(self, session) {
delete self.sessions[session.id];
};
let flush = function(self) {
let sessionService = self.app.get('sessionService');
let queue, session;
for(let sid in self.sessions) {
session = sessionService.get(sid);
if(!session) {
continue;
}
queue = self.sessions[sid];
if(!queue || queue.length === 0) {
continue;
}
session.sendBatch(queue);
self.sessions[sid] = [];
}
};