Worktile level the realization of the real-time information push service of millions

By Glen Garcia,2015-04-07 12:15
31 views 0
Worktile level the realization of the real-time information push service of millions

    Worktile level the realization of the real-time information

    push service of millions

    In a team collaborative toolsWorktileThe use of the process, you will find both in the top right corner of the notification, or drag task in the task pane, and the user's online status, real-time refresh.Worktile push service is in use is based on XMPP agreement, Erlang Ejabberd language implementation, and on the basis of its source, in combination with our business, to make the source code modified to fit our needs.In addition, based on closer agreement can also be used as a real-time news to push a choice, kick a net is to use the RabbitMQ + STOMP protocol implementation information push service.This article based on the practical project of my in Worktile and kick the net, introduces the information push service of concrete realization.

    The realization ways of real-time push

    Compared to on the phone message delivery way (generally in the Socket

    implementation), the WEB client is based on HTTP protocol, it is difficult to maintain a long connection like TCP.But with the development of technology, appeared the WebSocket, new technology such as Comet can achieve similar long connection effect, these techniques can be divided into the following categories:

    1) short polling.Asynchronous refresh the page side by JS timing, this way, the real-time effect is poorer.

    2) long polling.Page side by JS asynchronous request to the server, the server after receives the request, if the time request without the data, then hang the request, until there is data to or time slice (set) of a service that returns the request, the client and then the next request.The sample is as follows:

    3) the WebSocket.Browser through the WebSocket protocol connection server, realize the browser and server side full-duplex communication.Need the service side and browsers support WebSocket protocol.

    Method 1 in several ways, relatively simple, but the efficiency and real-time effect is poorer.Way 2 to the implementation of a service request is higher, especially the large quantity of concurrent cases, for a lot of pressure from the server.3 efficiency is higher, but the low version of the browser does not support, in addition the server also needs to have support WebSocket implementation.Worktile WEB side push, real-time news is XMPP XEP - 0124 BOSH (extension agreement, the essential way is to use 2 long polling.Kick net is adopted the connection of the RabbitMQ way, below I will introduce how to use these two approaches to realize the specific Server Push.

    The runtime environment

    Server-side implementation, whether by Ejabberd or the RabbitMQ, are based on the Erlang language development, so you have to install Erlang runtime environment.Erlang is a functional language, has the characteristics of fault tolerance and high concurrency, by means of the OTP function library, it is easy to build a robust distributed system.At present, the products are based on Erlang development, database aspects: Riak (chateau marmont implementation), CouchDB, Webserver: Cowboy, Mochiweb, message middleware are the RabbitMQ, etc.For the server-side programmer, Erlang provides high concurrency, fault tolerance and hot deployment feature is out of reach for other languages.Either in real-time communication or in the game, with Erlang can easy for each online user to create a corresponding Process, for a 4 core server 8 G, carrying millions of such a Process is very easy thing.Below is general schematic of Erlang program launch Process:

    As shown, Session Manager (or Gateway) for each user (UID) to create the corresponding Process, and the corresponding relations between (MAP) store the data in the table.Between each Process is corresponding to the user data, and they can send messages to

    each other.Erlang advantage is in the case of enough memory to create millions of such a Process, and its creation and destruction is more lightweight than JAVA Thread, both is not an order of magnitude.

    Ok, now we start Erlang environment construction (experimental system for Ubuntu 12.04, 4 nuclear 8 gb of memory) :

    1, the dependent libraries installed

    sudo apt-get install build-essential

    sudo apt-get install libncurses5-dev

    sudo apt-get install libssl-dev libyaml-dev

    sudo apt-get install m4

    sudo apt-get install unixodbc unixodbc-dev

    sudo apt-get install freeglut3-dev libwxgtk2.8-dev

    sudo apt-get install xsltproc

    sudo apt-get install fop tk8.5 libxml2-utils

    2, the official website to download OTP source packages

    (, unzip and install:

    tar zxvf otpsrcR16B01.tar.gz

    cd otpsrcR16B01


    make & make install

    At this point, Erlang runtime environment is completed.The following will introduce respectively the rabbitmq and ejabberd constructing real-time news service.

    Based on the RabbitMQ real-time news service

    The RabbitMQ message middleware is widely used in the industry, also is a kind of middleware to achieve the best closer accord.In closer agreement defines the Producer, Consumer, MessageQueue, Exchange, Binding, Virtual Host and other entities, their relationship as shown in the figure below:

    News publishers (Producer) to switch (Exchange), Exchange and Message Queue (Message Queue) through the KEY Binding, the Binding is based on Exchange types (into the Fanout, Direct, Topic, Header) respectively for different forms of distributing news.The Message Queue is divided into Durable, Temporary, Auto - Delete three types, Durable Queue is persistent Queue, will not disappear because of the service ShutDown, Temporary Queue will disappear after the service resume, Auto - Delete is automatically deleted when no Consumer connection.In addition the RabbitMQ there are a lot of third-party plug-ins, can make a lot of based on closer agreement based on the application of extension.Below we will introduce the WEB STOMP plug-in to build STOMP text protocol based on it, through a browser WebSocket achieve real-time message transmission.The structure of the system is shown in figure:

    As shown, WEB side we use STOMP. JS and SockJS JS and RabbitMQ WEB STOMP Plugin communication, mobile terminal can use STOMPj, Gozirra (Android) or Objc - STOMP (IOS) STOMP through agreement with the RabbitMQ to send and receive

    messages.Because we are real-time message system usually is to combine with an existing user system, the RabbitMQ can through a third party plug-in RabbitMQ - AYTH - Backend - HTTP adapter for the user's system, the plug-in can be done through the HTTP interface when the user to connect the certification process.Of course, there are the LDAP authentication and other ways.Here is the detailed steps:

    From the website ( the latest version of the source code package, unzip and install:

    tar zxf rabbitmq-server-x.x.x.tar.gz

    cd rabbitmq-server-x.x.x

    make & make install

    Install WEB - for the RabbitMQ STOMP plug-in

    cd /path/to/your/rabbitmq

    ./sbin/rabbitmq-plugins enable rabbitmq_web_stomp

    ./sbin/rabbitmq-plugins enable rabbitmq_web_stomp_examples

    ./sbin/rabbitmqctl stop

    ./sbin/rabbitmqctl start

    ./sbin/rabbitmqctl status

    Shown below will be displayed the operation of the plugin list

    Install the user authorization plug-in

    cd /path/to/your/rabbitmq/plugins

    wget <a


    cd ..

    ./sbin/rabbitmq-plugins enable rabbitmq_auth_backend_http

    Edit the RabbitMQ. Config file (default stored in/under the ECT/RabbitMQ /), add:



     {rabbit, [{auth_backends, [rabbit_auth_backend_http]}]},



     [{user_path, “http://your-server/auth/user”},

     {vhost_path, “http://your-server/auth/vhost”},

     {resource_path, “http://your-server/auth/resource”}




    User_Path is calibrated according to user's password, VHOST_Path is check to see if there is access to VHOST, Resource_Path is check the user of incoming Exchange, if the Queue have permission.I have the following code is to use the Node. Js example to realize the

    three interfaces:

    var express = require('express');

     var app = express();

     app.get('/auth/user', function(req, res){

     var name = req.query.username;

     var pass = req.query.password;

     console.log("name : " + name + ", pass : " + pass);

     if(name === 'guest' && pass === "guest"){







     app.get('/auth/vhost', function(req, res){




     app.get('/auth/resource', function(req, res){





    JS implementation browser end, the example code is as follows:


     var ws = new SockJS('http://' + window.location.hostname + ':15674/stomp');

     var client = Stomp.over(ws);

     // SockJS does not support heart-beat: disable heart-beats

     client.heartbeat.outgoing = 0;

     client.heartbeat.incoming = 0;

     client.debug = pipe('#second');

     var print_first = pipe('#first', function(data) {

     client.send('/exchange/feed/user_x', {"content-type":"text/plain"}, data);


     var on_connect = function(x) {

     id = client.subscribe("/exchange/feed/user_x", function(d) {




     var on_error = function() {



     client.connect('guest1', 'guest1', on_connect, on_error, '/');


    To be sure, we'll be the first to here in the RabbitMQ instance is created in the Feed this Exchange, we use STOMP. JS after the connection is successful, according to the current login user ID (user_x) to bind to the Exchange, namely the Subscribe

    ("/Exchange/Feed/user_x ",...).This operation behavior, so Feed in to the RabbitMQ Exchange sends the message and specify the user ID (user_x) as the KEY, can through the WEB page end Socket to receive this message in real time.

    So far, based on the RabbitMQ + STOMP to implement the WEB news push has been completed, many of them need friends to go to the details of the practice, there is not much.Practice can consult the official document:

    The implementation of the above is the way when I kick net use, then introduce below in Worktile now how to implement information push by Ejabberd.

    Based on the real-time news push Ejabberd

    Unlike the RabbitMQ, Ejabberd is one of the XMPP protocol implementation, compared with it, XMPP is widely used in instant communications.XMPP protocol implementation has a lot of kinds, such as JAVA OpenFire, but compared with other implementations, Ejabberd concurrent performance will surely make the best.XMPP protocol's predecessor is Jabber, early Jabber protocol mainly includes online status (Presence), friends Roster (Roster), IQ (Info/Query).Jabber has now become the RFC official standards, such as RFC2799 RFC4622, RFC6121, as well as the expansion of the XMPP protocol (XEP).Worktile remind function is based on Web side news XEP - 0124, XEP - 0206 definition of BOSH extension protocol.

    Due to their business needs, our user authentication and a friends list module for Ejabberd source, modified by Redis save the user's online status, rather than Mnesia and MySQL.Another friend this we (mongo) from an existing database to obtain project or a member of the team.Web side by Strophe. JS to connect (HTTP - BIND), Strophe. JS to long polling and WebSocket two ways to connect, because the Ejabberd haven't good WebSocket implementation, is the way the BOSH are adopted to simulate the long connection.The structure of the whole system is as follows:

    Web side use Strophe. JS connect via HTTP - BIND Nginx proxy, Nginx reverse proxy EjabberdCluster.IOS use XMPP - FramWork connection, Android can even directly with Smack Ejabberd server cluster.These are the existing libraries, don't need to make the development of the Client.Online status according to user's UID as KEY defines the online

and offline, busy deposit status in Redis.Buddy list from directing a Project table.User

    authentication directly modify the Ejabberd_Auth_Internal erl file, driven by directing a

    connected user libraries, online status is new functional modules, such as its part of the code

    is as follows:







     -define(SUPERVISOR, ejabberd_sup).


     -define(ONLINE, 1).

     -define(OFFLINE, 0).

     -define(BUSY, 2).

     -define(LEAVE, 3).


     %% API

     -export([start_link/2, get_proj_online_users/2]).

     %% gen_mod callbacks

     -export([start/2, stop/1]).

     %% gen_server callbacks

     -export([init/1, terminate/2, handle_call/3, handle_cast/2, handle_info/2, code_change/3]).

     %% Hook callbacks

     -export([user_available/1, unset_presence/3, set_presence/4]).

     -export([get_redis/1, remove_online_user/3, append_online_user/3]).

Report this document

For any questions or suggestions please email