pomelo的push机制(channel)和源码解读

原文来自:

尊重原创,转载请注明出处,谢谢!

pomelo是网易开源的服务器架构,通讯类型分为四种: request, response,, notify, push。

前面两种都可是使用pomelo.request实现,notify由pomelo.notify实现, 这里只看push是如何实现的。

一ChannelServiceChannelService是由pomelo默认加载组件channel创建的。 可以使用如下方法获得:app.get('channelService');ChannelService中提供了以下几个常用的方法:1 createChannel(name);name: channel名创建一个指定名称的channel。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;};2 getChannel(name, create);name: channel名create: 如果不存在, 是否创建获取一个指定用户名的channel, 如果create为true, 不存在会创建一个。ChannelService.prototype.getChannel = function(name, create) {var channel = this.channels[name];if (!channel && !!create) {channel = this.channels[name] = new Channel(name, this);}return channel;};3 destroyChannel(name);name: channel名使用name, 销毁一个指定的channel。ChannelService.prototype.destroyChannel = function(name) {delete this.channels[name];};4 pushMessageByUids(route, msg, uids, opts, cb);route: 前端消息监听方法的路由msg: 发送给前端的消息内容uids: 消息接收者 { uid: userId, sid: frontendServerId},uid为session.bind(uid);指定的opts: 可选的自定义参数cb: callback方法给指定uid推送消息。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);};5 broadcast(stype, route, msg, opts, cb)stype: 前端服务器类型route: 前端消息监听方法的路由msg: 发送给前端的消息内容opts: 可选的自定义参数cb: callback方法给指定服务器上所有的链接者推送消息。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 emptyutils.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 compatiblityopts.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上面是ChannelService对象提供的一些操作channel的方法, 下面是Channel对象的方法。1 add(uid, sid)uid: 前端连接的uidsid: 前端连接到的服务器id将uid添加到channel中。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;}};2 leave(uid, sid)uid: 用户的uidsid: 前端连接到的服务器id将uid从channel中移除。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;};3 getMembers()获取当前channel中所有的用户。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;};4 getMember(uid)uid: 用户的uid获取指定用户的uid。Channel.prototype.getMember = function(uid) {return this.records[uid];};5 destroy()销毁channel。Channel.prototype.destroy = function() {this.state = ST_DESTROYED;this.__channelService__.destroyChannel(this.name);};6 pushMessage(route, msg, opts, cb)route: 前端消息监听方法的路由msg: 发送给前端的消息内容opts: 可选的自定义参数cb: callback方法给当前channel中所有的用户推送消息。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);};看着它或是汹涌或是平静,然而一直相随,不离不弃。

pomelo的push机制(channel)和源码解读

相关文章:

你感兴趣的文章:

标签云: