Push mi, boom boom, touch mi ... Ajax Push Engine

    logoToday we’ll talk about Comet and server push in general.

    Conventional web applications, like sites, work according to the traditional request-response-request model, and due to the peculiarities of the HTTP protocol and some server implementations of the handlers, the application does not store information between requests, so that each call is independent, and the identification or session support is provided by higher-level means (for example, the well-known implementation of sessions in PHP). In addition, a request for new information is always sent by a client who is interested in obtaining the most current version of the data. In applications that are critical of updating, this often becomes a bottleneck. In one of our previous projects, we had several periodic AJAX requests for updating data at once. Although for this case there are options for calling several handlers on the server side with a single request from the client.


    But there is another approach, when the server independently determines that there is new data (and it will be the first to know about it) and delivers it to the client program, which does not spend time on requests, but receives it when something new has appeared. For this, however, it is necessary to keep the connection to the server constant, for example, through a bi-directional socket. And if in traditional software there are no special difficulties with this, it is quite difficult to implement long-term persistent connections for web applications. This is done through the IFrame in the most primitive way, but this is not the only possibility, and the developers of top libraries and plugins have tried it, so look in your favorite framework, the Comet implementation should be there (it definitely is in the Dojo Toolkit, there are plugins for jQuery , built-in feature in GWT).in this set of materials .

    But how to make a server? The usual version of Apache + PHP is poorly suited, although, of course, it is possible on it, but the solution will be far from optimal and will not withstand the typical load. Speaking of load. For Comet applications, the load is the number of clients that can be served at the same time, which means the number of open connections with clients, rather than data transfer. And the number of such connections for ordinary servers should reach tens of thousands, typical numbers - 20 - 50 thousand connections in parallel. And here the Apache / PHP bundle does not help. We need something else.

    For the Java world, there are implementations for application servers, for example, Jetty (probably the most famous and standard implementation of Comet, here is a good article in Russianfrom IBM), a server framework based on the Grizzle - Atmosphere platform appeared not so long ago , so implementing your own logic and your own server for a specific application will not be difficult.

    What else to do? I can recommend an open APE project or Ajax Push Engine. This is a small server written in C, which compiles as a daemon and listens to its port, by default, 6969, but it can also be configured to work with Apache. Unlike other solutions, APE is a specialized HTTP server that supports GET / POST requests, that is, you can connect to the server from any language and system, if only HTTP requests are understood. And this is a self-sufficient solution, in principle, it can be limited to APE alone, without additional servers (in Jetty, the implementation still requires an application server and a web server). According to the developers, APE works perfectly under load and is able to hold up to 100 thousand connections at the same time, and horizontal scaling will be added in the future.


    It should be noted that in its architecture, the APE project consists of three parts:
    • epoll-driven HTTP server is the very foundation, a server that processes connections and keeps connections, allowing Server push to be implemented in any way that is appropriate for the client, whether it be XHR long-polling or through iframes, and in the future native browsers will be utilized (for example, web sockets)
    • APE JavaScript Framework is an equally important part of the project, a client script based on MooTools that can integrate server capabilities into any AJAX client application. It also implements a modular system and extensions, so you can write any wrapper for another library on top or transparently embed in your solution. The library implements imitations of sockets and pipe, so that the developer gets a fairly high-level abstraction, and if you climb even higher, then an event model is available to him and you can simply forget about the implementation details.
    • Plugin system - the server can be expanded by adding its own functionality through plug-ins. Now it is available only through C-modules, however they are extremely simple, server-side JavaScript is expected in the future, which will be a really great solution (oh, you could screw the PHP there, although, of course, it is possible through a simple C-plugin, but still).

    On the server side, APE uses the epoll engine, as well as a hash table implementation (DJB Hash Algorithm). This, in addition to maximum performance, also results in difficulties in porting - the server wants to build the Linux kernel 2.6.19+ and libc6-dev, and so far I have not succeeded in getting it to build under Cygwin (the stopper is precisely in terms of the epoll mechanism built into the kernel )

    APE implements several methods for exchanging information between the server and the client, as well as between clients (through the server). The first one is Channels, when users subscribe to certain channels, and when new information associated with this channel appears on the server, it is transmitted to all clients listening to the channel. Thus, you can immediately send out new data to all customers, which can be an unlimited number. APE can also be used as a queue of messages stored in memory - each connected user has one or more queues. The recipient of the message can be either a channel, then everyone will receive the message, either directly another user or an external service. Channels can be either interactive or read-only.

    APE takes on the role of a proxy server, allowing you to exchange messages with external services (for example, your application server), as well as receive data from them and send them to channels or to specific users. Thus, it is possible to build a system in which the front-end for users will be APE, which processes connections, and then the back-end server will work, delivering and receiving data in the form of messages via the APE internal protocol, but knowing nothing about the number of connected clients , he only needs to be able to communicate with the APE server.


    The interaction between the client and server is done through a special protocol . Users can initiate commands, for example, send a message or create a connection, in response to which the server sends RAW data, usually it is JSON. However, server modules can extend the built-in command set, so you can describe your own set of actions, depending on your needs.

    Although the official documentationstill in development (of course, this is a wiki), and does not report on available modules, several basic modules are available in the source repository, which can be useful both as a reference tool for developing your solutions and for embedding into an existing infrastructure. For example, libape-mysql allows you to connect to the database and get new information from there (however, note that the module version is 0.01), and libape-chat will show a demo version of a simple chat system. The most interesting promises to be libape-spidermonkey, although so far there is no information about it except the source.

    The project is very young, but it already shows its potential, so if you plan to start any serious applications that require simultaneous work with many users (chat or game system), or data delivery is critical, I advise you to pay attention to APE.

    PS If anyone can build this server under Win32 system - please share the solution!

    Also popular now: