Skip to content
This repository has been archived by the owner on Sep 25, 2023. It is now read-only.

Distributed Chat

py8765 edited this page Oct 29, 2012 · 35 revisions

Why chat?

Pomelo is a game framework, why the tutorial starts from chat?

Pomelo is really a game framework, but it is essentially a high real-time, scalable, multi-process application framework. In addition to the special part of the game library in the library section, the rest of the frame can be completely used for the development of real-time web application. And compared with some node.js high real-time application framework such as derby, socketstream, meteor etc, it has a better scalability.

Because of the complexity of the game in scene management, client Animation, they are not suitable entry level application for the pomelo. Chat application is usually the first application which developers contact with node.js, and therefore more suitable for the tutorial.

Generally the entry application of node.js is based on socket.io development of ordinary chat rooms. Because it is based on single-process node.js development, it hit a discount in scalability. For example, if you want to improve it to a multi-channels chat room like irc, the increase number of channels will inevitably lead the single-process node.js overloaded.

From a single process To multi-process, From socket.io To pomelo

A native chat room application based socket.io, take [uberchat] (http://github.com/joshmarshall/uberchat ) for example.

Its application architecture diagram is as below:

uberchat

The server which only contains a single node.js process receives requests from websocket.

It has following disadvantages:

  1. Poor scalability: only support single process node.js, can not distribute according to room/channel, and can not separate broadcast pressure from logic business processing either.

  2. Code redundancy: make simple encapsulation of socket.io, and only the server side contains 430 lines of code.

Using pomelo to write this framework can be completely overcome these shortcomings.

The distributed chat application architecture which we want to build is as follow:

multi chat

In this architecture, the front-end servers named connector is responsible for holding connections, the chat server is in charge of processing business logic.

Such scale-up architecture has following advantages:

  • Load separation: The architecture totally separates the connection code from the business logic code, and this is really necessary especially in broadcast-intensive application like game and chat.Intensive broadcast and network communication consume large amount of resource, however, the business logic processing ability will not be influenced by broadcasting because of the separated architecture.

  • Simple switch: Users can switch channels or rooms that do not need to reconnect websocket because of this separated architecture.

  • Good scalability: We can launch more connector processes to deal with the increase of users, and use hash algorithm to map channels to different servers.

Below, we will start to build this application with pomelo, and we will find that it only needs less than 100 lines of code to build such a complex architecture.

Initialization of Code Structure

Application of the code structure can be initialized by using the following command:

$:pomelo init chatofpomelo

The code structure is shown below:

chat directory

Description:

  • game-server: all the game business logic code is in this directory.The file app.js is the entrance of the server, and all the game logic and functions start from here.

  • web-server: web server which used by game server(including login logic), the client js, css and static resources.

  • config: Generally, a project needs a lot of configurations and you can finish them by JSON files here. In game project, some configurations have be created such as log, master-server and other servers at initialization. Also, you can add database, map and numerical tabular configuration etc.

  • logs: Logs are essential for the project and contain a number of infomations which you can get the project runing state from.

  • shared: Both some configurations and code resources can be shared between front end and back end if you choose javascript to run client.

Initialization && Test:

install npm package

$:sh npm-install.sh

start game server

$:pomelo start

start web server

$:cd web-server && node app.js

The web server contains the pomelo client, when the web server is started, the client is automatically loaded into the browser. Clients send requests to the game server via websocket, the server can push messages to the client after connected by pomelo.

test

Enter http://localhost:3001, if the web server is running successfully, the following page will appear in the browser:

welcome page

Click the Test Code button, the pop of 'hello, pomelo' prove the success of the client and server communication.

The start of Chat Logic Coding

The logic of chat includes the following sections:

  • Entering: this part of the logic is responsible for registering user information to session, and add user into the channel of chat room.

  • Chatting: this section includes sending requests from the client, and receiving requests by the server.

  • Broadcasting: all clients in the same chat room receive and show messages.

  • Leaving: this section needs to do some clean-up work, including cleaning up the session and channel information.

Entering

Achieved function effect is as shown below: User enters user name, name of chat room, user joins the chat room.

Client

Clients need to send a request to the server, the first request must give to the connector process, because the server needs to register the session information for the first time(page code layout in this tutorial omitted).

pomelo.request('connector.entryHandler.enter', function(){
}); 

The above request string 'connector.entryHandler.enter' representing the name of server type, the file name of the service and the corresponding method name respectively.

Server

The connector receiving messages doesn't need any configuration, only create a new file named entryHandler.js under the connector/handler directory. We just need to implement the enter method, and the server will automatically perform the corresponding handler, the specific code is as follows:

handler.enter = function(request, session, next) {
	session.userLogined(uid);
	session.on('closing', onUserLeave);
};

Server add user into channel

Using the rpc method to add the logged in user into the channel.

app.rpc.chat.chatRemote.add(session, uid, opts, function(data){});

app is the object of pomelo, app.rpc represents the remote rpc call between the front and the end servers, the last three parameters correspond to the server name, the file name and the name of the method respectively. In order to finish this rpc call, you only need to create a new file named chatRemote.js in chat/remote directory, and implement the add method.

handler.add = function(uid, opts, cb){
    var channel = channelService.getLocalChannelSync(opts); 
    if(!!channel)
        channel.add(uid, null, cb);
};
Clone this wiki locally