Pomelo's push mechanism (channel) and Source code interpretation

Source: Internet
Author: User

Originally from: http://blog.csdn.net/xufeng0991/article/details/45499665

Respect the original, reproduced please indicate the source, thank you!


Pomelo is NetEase open source server architecture, the type of communication is divided into four kinds: request, response, notify, push.

The first two types are implemented using Pomelo.request, notify is implemented by Pomelo.notify, here only see how push is implemented.


A channelservicechannelservice is created by the Pomelo default loading component channel. You can use the following methods to obtain:
App.get (' Channelservice ');

The following common methods are available in Channelservice:
1 CreateChannel (name); Name:channel Name
Creates a channel with the specified name.
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 name
Create: If not present, creates
Gets a channel that specifies the user name, if Create is true, does not exist creates one.
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
Use name to destroy a specified channel.
ChannelService.prototype.destroyChannel = function (name) {    delete this.channels[name];};

4 Pushmessagebyuids (Route, MSG, UIDs, opts, CB); route: routing of the front-end message listener method
MSG: message content sent to the front end
UIDs: Message Recipient {
Uid:userid,
Sid:frontendserverid
},
UID is session.bind (UID);
of the specified
OPTs: Optional Custom parameters
Cb:callback method
Pushes a message to the specified 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 is 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: Front End server type
Route: Routing of the front-end message listener method
MSG: message content sent to the front end
OPTs: Optional Custom parameters
Cb:callback method
Pushes a message to all the linker on the specified server.
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.invokecall            Back (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 ()); }};


The second channel above is the Channelservice object provides some way to operate the channel, the following is the method of the channel object.
1 Add (UID, sid) UID: UID for front-end connection
SID: The server ID to which the front-end is connected
Adds the UID to the channel.
Channel.prototype.add = function (uid, sid) {    if (This.state > st_inited) {        return false;    } else {        var r ES = Add (uid, sid, This.groups);        if (res) {            This.records[uid] = {                Sid:sid,                uid:uid            };        }        return res;    }};

2 Leave (UID, sid) UID: UID of the user
SID: The server ID to which the front-end is connected
Removes the UID from the 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 () gets all the users in the current 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 of the user
Gets the UID of the specified user.
Channel.prototype.getMember = function (UID) {    return this.records[uid];};

5 Destroy () Destroy channel.
Channel.prototype.destroy = function () {    this.state = st_destroyed;    This.__channelservice__.destroychannel (this.name);};

6 Pushmessage (Route, MSG, opts, CB) Route: The route of the front-end message listener method
MSG: message content sent to the front end
OPTs: Optional Custom parameters
Cb:callback method
Pushes messages to all users in the current 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);};


Three summary from the methods provided above, it can be seen that there are two ways to achieve push:
1 Anonymous channel is no need to create channel, directly using Channelservice.pushmessagebyuids and channelservice.broadcast push;
Example:
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);    }});

2 Explicit channel requires the use of Channel.createchannel or Channel.getchannel to obtain a channel first and then push with Chanel.pushmessage.
Example:
Create Channelvar channelname = ' Allpushchannel '; var channel = this.channelservice.getchannel//Add the user to the channel inside if (!!) Channel) {    channel.add (uid, sid);} Push message according to channel name var channelname = ' Allpushchannel '; var pushchannel = This.channelService.getChannel (ChannelName, False);p ushchannel.pushmessage (' onmsg ', {    msg:msg}, function (err) {    if (err) {        console.log (err);    } else {        Console.log (' push ok ');}    });

Reference
Official api:http://pomelo.netease.com/api.html
Cnodejs:https://cnodejs.org/topic/51b531bef78196a85c4f0c89

Pomelo's push mechanism (channel) and Source code interpretation

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.