Filed under: nginx

App Engine Channel API in AppScale

One of Google's newest App Engine features is the Channel API which allows for the pushing of messages to a client's javascript code. This blog entry explains AppScale's scalable implementation which is built using ejabberd and strophejs. 

There are two sets of APIs for the developer. First is the python API which consists of create_channel(app_client_id) and send_message(app_client_id, message). The create channel API under the covers uses the xmpp service implementation of AppScale. We are able to leverage ejabberd to take care of the distribution and sending of messages for us. The trick here lies in that we must create temporary accounts with each new channel created. This requires garbage collection of channels which live on longer than a prescribe period of time. 

Second, is the javascript API which can be included into the developer's code by adding the following line in the head of the html:
<script src='/_ah/channel/jsapi'></script>
This API allows for the creation of connections using strophejs. Strophejs is a robust and open source project that enabled BOSH connections to ejabberd (https://github.com/metajack/strophejs). The creation of a channel socket is actually using strophejs's connections, as well as its message callbacks. The functions have the same name and functionality to preserve the API, but the implementation is different. Google's implementation uses google talk and their xmpp service. Their javascript in production is minified and hard to decode while their SDK version uses polling instead of long lived BOSH connections (500ms poll time). AppScale's javascript library is also minified to save on bandwidth, yet the unminified version can be found in appscale/AppServer/google/appengine/tools/appscale-js.js. Within this file you will see a goog.appengine library to maintain the APIs as well as the strophe library along with additional libraries of MD5 and SHA which are needed by strophe. 

Nginx is used as a proxy to connect to ejabberd's http bind path (see http://tinyurl.com/68qbwyc on why a proxy is needed). The proxy connects to port 5280 to ejabberd's http-bind path. Long lived ajax calls are created to provide low overhead as opposed to constant polling. This can be seen when using resource tracking with Firefox or Chrome. You'll notice a call which blocks until a message is returned, followed immediately by another long lived connection. The javascript library also listens to the unload event where the client window is closed. Before a full exit, the client library will send a disconnect message to free up resources. 

AppScale's implementation allows for sending messages to multiple receivers which is more functionality then the one sender and one receiver restriction in GAE. Any clients given the same application key will see messages which are sent to that application when using the send_message(client_id, message) function. 

Naming issues
Each xmpp account is registered as <username>@<head-ip>, where username is the first part of your email (i.e. joe.smith of joe.smith@gmail.com). This reserves that username, and restricts other emails which the same username name (i.e. joe.smith@yahoo.com). 

The xmpp API implementation also creates an xmpp account for each app. If your username conflicts with an appname, you will not be able to use that email. We have ideas on how to alleviate this problem but its low on our list. If we see that users definitely don't like this limitation we will address it. 

The User/App Server within AppScale, which is a SOAP frontend to the APPS and USERS table in the datastore, must keep track of which User entry is an app, user, or channel. This is for authentication and also to know which accounts need to be garbage collected.  

Scalable Implementation
In order to have xmpp scale we need DNS. Without it we cannot route between machines because their domain (ip address) is different. The default setting will be to route all messages to the head node using nginx, but we will support DNS configuration for the advance users in the future. 
1 of 1


Posterous theme by Cory Watilo