Analysis of chatofPomelo game-server

Source: Internet
Author: User

Analysis of chatofPomelo game-server

ChatOfPomelo is a chat room program. I will analyze the game-server on the chat server.
First, let's look at its file structure.

The large structure is consistent with hellopomelo, and has app, config, logs, node_modules, and app. js.
With the hello experience, let's go straight to the topic config/servers. json
The custom server configuration is configured here.

{    development:{        connector:[             {id:connector-server-1, host:127.0.0.1, port:4050, clientPort: 3050, frontend: true}         ],        chat:[             {id:chat-server-1, host:127.0.0.1, port:6050}        ],        gate:[           {id: gate-server-1, host: 127.0.0.1, clientPort: 3014, frontend: true}        ]    },    production:{           connector:[             {id:connector-server-1, host:127.0.0.1, port:4050, clientPort: 3050, frontend: true}         ],        chat:[             {id:chat-server-1, host:127.0.0.1, port:6050}        ],        gate:[           {id: gate-server-1, host: 127.0.0.1, clientPort: 3014, frontend: true}        ]  }}

We can see that the development and production environments are configured in the same way.
This chat room is composed of three custom services.
Gate, chat, connector
Gate-front-end gateway service, used for initial connection with the server and allocating connector to the client
Connector-frontend connection server, used to maintain a persistent websocket connection with the client and forward the Protocol processed by the backend server
Chat-backend chat Server. The client cannot connect to it. The processed logic is passed to the client through connector.
Look at the directory structure of the three services

Noted that gate, connector as front-end service thick ky "http://www.bkjia.com/kf/ware/vc/" target = "_ blank" class = "keylink"> vcsy/connectors/rzQPGJyIC8 + DQq2 + connectors/rzQPGJyIC8 + connector + vNCx7cq + 0qq0psDt0 + u/keys + C52LXEysK8/keys + 1PKx7cq + tKbA7bf + weight + u + weight/Nu6e2y8/ycG9tZWxvx + weight/aPGJyIC8 + DQq/tL + weight + bandwidth = "brush: java; ">Module. exports = function (app) {// export handler class return new Handler (app) ;}; var Handler = function (app) {this. app = app ;}; var handler = Handler. prototype; handler. queryEntry = function (msg, session, next) {// the unique interface used by the client to access gate var uid = msg. uid; if (! Uid) {next (null, {code: 500}); return;} // get all connectors var connectors = this. app. getServersByType ('ctor ctor '); if (! Connectors | connectors. length = 0) {next (null, {code: 500}); return;} // here we just start 'one' ctor server, so we return the connectors [0] var res = connectors [0]; // next returns the message next (null, {code: 200, host: res. host, port: res. clientPort });};

EntryHandler. js (this file is under the connector directory, no matter what its name is, it is a connector module)

Module. exports = function (app) {return new Handler (app) ;}; var Handler = function (app) {this. app = app ;}; var handler = Handler. prototype; // the handler that the client accesses to connector. enter = function (msg, session, next) {var self = this; var rid = msg. rid; var uid = msg. username + '*' + rid // sessionService is the default service provided by pomelo. It maintains the session information var sessionService = self. app. get ('sessionservice'); // duplicate log in if (!! SessionService. getByUid (uid) {next (null, {code: 500, error: true}); return;} session. bind (uid); session. set ('rid ', rid); session. push ('rid ', function (err) {if (err) {console. error ('set rid for session service failed! Error is: % j ', err. stack) ;}}); session. on ('closed ', onUserLeave. bind (null, self. app); // Add players to the chat service by calling rpc, and return the gamer list to the client self. app. rpc. chat. chatRemote. add (session, uid, self. app. get ('serverid'), rid, true, function (users) {next (null, {users: users}) ;}; // After the player closes browsing, call chatRemote through rpc to notify chatRemote to delete the player var onUserLeave = function (app, session) {if (! Session |! Session. uid) {return;} app. rpc. chat. chatRemote. kick (session, session. uid, app. get ('serverid'), session. get ('rid '), null );};

Chat is divided into two parts: handler and remote
Handler indicates that it needs to process client information
Remote indicates that it processes information from backend servers.
Since our connecotr uses the add and kick of chat, let's take a look at the remote content first.
Chatremote. js

Module. exports = function (app) {return new ChatRemote (app) ;}; var ChatRemote = function (app) {this. app = app; this. channelService = app. get ('channelservice'); // the channel is also the default server of pomelo }; // Add the player to the specified channel uid player id sid server id name channel name flag channel identifier ChatRemote. prototype. add = function (uid, sid, name, flag, cb) {var channel = this. channelService. getChannel (name, flag); var username = uid. split ('*') [0]; va R param = {route: 'onadd', user: username}; channel. pushMessage (param); if (!! Channel) {channel. add (uid, sid);} cb (this. get (name, flag) ;}; // gets the player information from the channel. The channel name flag channel parameter is returned to the player list ChatRemote. prototype. get = function (name, flag) {var users = []; var channel = this. channelService. getChannel (name, flag); if (!! Channel) {users = channel. getMembers () ;}for (var I = 0; I <users. length; I ++) {users [I] = users [I]. split ('*') [0];} return users ;}; // gets the player from the channel to play ChatRemote. prototype. kick = function (uid, sid, name) {var channel = this. channelService. getChannel (name, false); // leave channel if (!! Channel) {channel. leave (uid, sid);} var username = uid. split ('*') [0]; var param = {route: 'onleave ', user: username}; channel. pushMessage (param );};

It can be seen from the code that it is a method to deal with the internal components of pomelo. The code is simple, but all the messages sent to the client are completed through the channel. the channel is completed through connector, so the server and the client are not directly connected and are all transferred through connector.

Chat. handler: In pomelo, handler processes client messages. However, since chat is not a front-end server, the send event is captured by connector and then route, instead of connecting the client directly to the chat server.

Var chatRemote = require ('.. /remote/chatRemote '); module. exports = function (app) {return new Handler (app) ;}; var Handler = function (app) {this. app = app ;}; var handler = Handler. prototype; // process the received client message handler forwarded by connecotr. send = function (msg, session, next) {var rid = session. get ('rid '); // gets the channel id var username = session specified by the player. uid. split ('*') [0]; var channelService = this. app. get ('channelservice'); var param = {msg: msg. content, from: username, target: msg.tar get}; channel = channelService. getChannel (rid, false); // obtain the channel instance corresponding to this server through the channelid // the target is all users if(msg.tar get = '*') {channel. pushMessage ('onchat', param); // the channel sends the message to the client through ctor} else {// the target is specific user var tuid = msg.tar get + '*' + rid; var tsid = channel. getMember (tuid) ['sid ']; channelService. pushMessageByUids ('onchat', param, [{uid: tuid, sid: tsid}]);} next (null, {route: msg. route });};

Finally, let's take a look at the entire network structure.

The gate is unique and serves as the gate. The client initiates a connection with the gate first, and the gate determines the connection between the client and the connecotr. The gate can act as a server Load balancer.
There can be multiple ctor groups. They are responsible for hosting connections from clients and interacting with backend chatrooms.
There can also be multiple chatrooms, and each chat can correspond to different ctor.
The backend chatroom is not directly connected to the client.

 

Related Article

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.