标签:pomelo
原文来自:http://blog.csdn.net/xufeng0991/article/details/45499665
尊重原创,转载请注明出处,谢谢!
pomelo是网易开源的服务器架构,通讯类型分为四种: request, response, notify, push。
前面两种都可是使用pomelo.request实现,notify由pomelo.notify实现, 这里只看push是如何实现的。
app.get('channelService');ChannelService.prototype.createChannel = function(name) {
if (this.channels[name]) {
return this.channels[name];
}
var c = new Channel(name, this);
this.channels[name] = c;
return c;
};ChannelService.prototype.getChannel = function(name, create) {
var channel = this.channels[name];
if (!channel && !!create) {
channel = this.channels[name] = new Channel(name, this);
}
return channel;
};
ChannelService.prototype.destroyChannel = function(name) {
delete this.channels[name];
};ChannelService.prototype.pushMessageByUids = function(route, msg, uids, opts, cb) {
if (typeof route !== 'string') {
cb = opts;
opts = uids;
uids = msg;
msg = route;
route = msg.route;
}
if (!cb && typeof opts === 'function') {
cb = opts;
opts = {};
}
if (!uids || uids.length === 0) {
utils.invokeCallback(cb, new Error('uids should not be empty'));
return;
}
var groups = {},
record;
for (var i = 0, l = uids.length; i < l; i++) {
record = uids[i];
add(record.uid, record.sid, groups);
}
sendMessageByGroup(this, route, msg, groups, opts, cb);
};ChannelService.prototype.broadcast = function(stype, route, msg, opts, cb) {
var app = this.app;
var namespace = 'sys';
var service = 'channelRemote';
var method = 'broadcast';
var servers = app.getServersByType(stype);
if (!servers || servers.length === 0) {
// server list is empty
utils.invokeCallback(cb);
return;
}
var count = servers.length;
var successFlag = false;
var latch = countDownLatch.createCountDownLatch(count, function() {
if (!successFlag) {
utils.invokeCallback(cb, new Error('broadcast fails'));
return;
}
utils.invokeCallback(cb, null);
});
var genCB = function() {
return function(err) {
if (err) {
logger.error('[broadcast] fail to push message, err:' + err.stack);
latch.done();
return;
}
successFlag = true;
latch.done();
};
};
opts = {
type: 'broadcast',
userOptions: opts || {}
};
// for compatiblity
opts.isBroadcast = true;
if (opts.userOptions) {
opts.binded = opts.userOptions.binded;
opts.filterParam = opts.userOptions.filterParam;
}
for (var i = 0, l = count; i < l; i++) {
app.rpcInvoke(servers[i].id, {
namespace: namespace,
service: service,
method: method,
args: [route, msg, opts]
}, genCB());
}
};
Channel.prototype.add = function(uid, sid) {
if (this.state > ST_INITED) {
return false;
} else {
var res = add(uid, sid, this.groups);
if (res) {
this.records[uid] = {
sid: sid,
uid: uid
};
}
return res;
}
};Channel.prototype.leave = function(uid, sid) {
if (!uid || !sid) {
return false;
}
delete this.records[uid];
var res = deleteFrom(uid, sid, this.groups[sid]);
if (this.groups[sid] && this.groups[sid].length === 0) {
delete this.groups[sid];
}
return res;
};
Channel.prototype.getMembers = function() {
var res = [],
groups = this.groups;
var group, i, l;
for (var sid in groups) {
group = groups[sid];
for (i = 0, l = group.length; i < l; i++) {
res.push(group[i]);
}
}
return res;
};Channel.prototype.getMember = function(uid) {
return this.records[uid];
};Channel.prototype.destroy = function() {
this.state = ST_DESTROYED;
this.__channelService__.destroyChannel(this.name);
};
Channel.prototype.pushMessage = function(route, msg, opts, cb) {
if (this.state !== ST_INITED) {
utils.invokeCallback(new Error('channel is not running now'));
return;
}
if (typeof route !== 'string') {
cb = opts;
opts = msg;
msg = route;
route = msg.route;
}
if (!cb && typeof opts === 'function') {
cb = opts;
opts = {};
}
sendMessageByGroup(this.__channelService__, route, msg, this.groups, opts, cb);
};
var uidArray = new Array();
uidObject.uid = "session uid";
uidObject.sid = "connector-server-1";
uidArray.push(uidObject);
channelService.pushMessageByUids('onMsg', {
msg: msg
}, uidArray, function(err) {
if (err) {
console.log(err);
return;
}
});
channelService.broadcast('connector', 'onMsg', msg, {
binded: true
}, function(err) {
if (err) {
console.log(err);
}
});//创建Channel
var channelName = 'allPushChannel';
var channel = this.channelService.getChannel
//把用户添加到channel 里面
if (!!channel) {
channel.add(uid, sid);
}
//根据Channel名字推送消息
var channelName = 'allPushChannel';
var pushChannel = this.channelService.getChannel(channelName, false);
pushChannel.pushMessage('onMsg', {
msg: msg
}, function(err) {
if (err) {
console.log(err);
} else {
console.log('push ok');
}
});标签:pomelo
原文地址:http://blog.csdn.net/xufeng0991/article/details/45499665