Back to blogging: What to expect

Hello Readers,

I started this blog as a way to share my experiments and experiences while learning web development and computer science in general. In the first 2 years (between Apr’08 and Aug’10) I wrote as many as 100 blog posts. Quite a frenzy. Ever since, I only managed to write 5-6 posts in the following 4 years, about nearly 45 drafts which may now never get published. Good thing is that, I am back to blogging, which means a lot to share.

Briefly, here is what (or what not) to expect in the future posts:

  1. PHP – In past, PHP has dominated the content on this blog. Mostly web demos, some quick hacks or some JAXL library examples. However, I am no longer working actively with PHP since ’10 and probably never saw it after ’12. Expect zero PHP.

  2. JAXL – No more PHP essentially means no more JAXL posts. In fact, I recently moved JAXL repository to it’s own Github organization where other collaborators can maintain, improve and work on it without requiring my active involvement. This organization also contains other repositories that I managed to open source from my startup Jaxl.

  3. XMPP – Unfortunately, I am no longer in touch with progress on XMPP specifications. Specs has evolved a lot, to an extent that some developers have reported mod_message_carbon no longer works as expected with new Ejabberd server version (also, Message Carbon extension XEP-0280 has itself been deprecated). However, XMPP will always be my preferred choice whenever I need entire suite of user-to-user, group messaging, presence, contacts management, Jingle / SIP integration and other features baked into XMPP XEPs. For my everyday messaging needs, new technologies like ZeroMQ, AMQP (RabbitMQ), MQTT or even Redis PubSub are more suitable.

  4. Java – After some journey I am now finally working full-time with Java. I still hate it but trying to adapt, learn and love it for at least what it’s worth for.

  5. Python – Thanks to my stint with Appurify, I had a chance to work full-time with Python. I even managed to work on some interesting open source Python projects. Even though now it’s no longer my primary language, Python is always fun specially when one is in a hurry of getting things done.

  6. Golang / Erlang – I met Golang a year back. I met Erlang while hacking Ejabberd, Riak etc for my startup Jaxl and immediately fell in love with it. Nowadays, I am in love with Golang. It’s simple and precise, has similar message passing semantics (buffered channels) as found in Erlang (mail boxes). I highly recommend digging into these languages and getting comfortable with message passing programming paradigm. They will change how you approach and think about your application structure. Expect lots of Golang and some Erlang.

  7. Docker – Who is not into docker these days? If that’s not the case with you, leave this post right now and head over to docker user guide. That’s how important I find this piece of beauty (technology). Expect a lot about docker in my future posts.

  8. Startups – A lot of startup fun has kept me busy since ’10, some experiences and learnings are worth sharing.

  9. Android – I have been working full-time with mobiles (both Android and iOS) since ’12. Not much of application making but a lot of hacking with Adb protocol and libimobiledevice.

  10. System designing – Luckily, I happened to experience a lot of end-to-end system and network designing. This domain is of great interest once you start to have fun with Racks, Subnet, Routes, Switches, Firewalls, DNS, Multi-cast and entire suite of technology under this umbrella.

Will end this post with some interesting images from the past.

Fsck'd iPhone screen
Swollen iPhone screen due to high device temperature
Rackframe
Setting up Racks

Working with Jaxl – A Networking Library in PHP – Part 1 – An Introduction, Philosophy and History

Development of Jaxl library started way back in December’07 while I was working on a self-initiated project called Gtalkbots. The project is now dead, if you are interested in knowing more about it go through Gtalkbots BlogSpot. Jaxl v1.x was first released in Jan’09 and about a year later in Aug’10 Jaxl v2.x was released. First two versions were released as JAbber XMPP Library for writing clients and external server components.

While working on my startup Jaxl – A Platform As A Service (PAAS) for developing real-time applications, I started experiencing v2.x limitations when my external server side components were unable to process XMPP packets at the speed they were sent by ejabberd server. I started restructuring and refactoring the library which gave birth to Jaxl v3.x. Since v3.x was initially being used for developing the entire infrastructure, it shaped up as a networking library in PHP with stable support for XMPP protocol. However, later I had to rewrite several infrastructure components in Erlang Programming Language due to several issues that PHP as a language couldn’t solve (after all PHP wasn’t made for such tasks). Finally in April’12, Jaxl v3.x was open sourced.

Jaxl v3.x is an asynchronous, non-blocking, event based networking library in PHP for writing custom TCP/IP client and server implementations. From previous versions, Jaxl library inherits a full blown stable support for XMPP protocol stack. In v3.0, support for HTTP protocol stack was also introduced. At the heart of every protocol stack sits a Core stack. It contains all the building blocks for everything that we aim to do with Jaxl library. Both XMPP and HTTP protocol stacks are written on top of the Core stack. Infact the source code of these protocol implementations knows nothing about the standard (inbuilt) PHP socket and stream methods.

Philosophy
Jaxl is designed to work asynchronously in a non-blocking fashion and provides an event based callback API. Now what does all that mean?

By non-blocking and asynchronous it means, when a library function like:
$jaxl->send($stanza); is called, it will return immediately i.e. this function call will NOT block any further execution of your application script until $stanza has actually been sent over the connected TCP socket. Infact, when this function is called, passed $stanza object is put into an output buffer queue, which will be flushed as and when underlying TCP socket is available for writes. Similarly, most of the available methods (wherever required and possible) inside Jaxl library are non-blocking and asynchronous in nature.

By event based callback API it means, application code will need to register/add callbacks over necessary events as they occur inside Jaxl instance lifecycle. A list of available event callbacks with some explanation can be found here. For example, most of the XMPP applications will usually register a callback over on_auth_success event. As and when this event occurs inside Jaxl instance lifecycle, registered function will be callback’d with necessary parameters (if any).

Related Links

  • Read library documentation
  • Download the latest and greatest source from GitHub.
  • Have any Question? Want to discuss? Need Help? Use Google Group/Forum.
  • Found something missing or a bug in the source code? Kindly report an issue.
  • Fixed a bug? Want to submit a patch? Want to improve documentation? Checkout source code and contribute to the library

XMPP Application Examples

HTTP Application Examples

Stay Tuned
In coming weeks, under this series of blog posts titled “Working with Jaxl – A Networking Library in PHP”, I will cover following major topics with sample code:

  • Explanation of each Core stack class and how to use them
  • Design of each XMPP and HTTP stack class
  • XMPP over HTTP
  • XMPP File Transfer and Multimedia Sessions
  • Understanding and Using External Jabber Components
  • Asynchronous Job/Task Queues
  • Developing Concurrent and Parallel Systems

If you have any specific topic that you would like me to be cover, kindly let me know via your comments here.

Announcing Jaxl v3.x – asynchronous, non-blocking I/O, event based PHP client/server library

Jaxl v3.x is a successor of v2.x (and is NOT backward compatible), carrying a lot of code from v2.x while throwing away the ugly parts. A lot of components have been re-written keeping in mind the feedback from the developer community over the last 4 years. Also Jaxl shares a few philosophies from my experience with erlang and python languages.

Jaxl is an asynchronous, non-blocking I/O, event based PHP library for writing custom TCP/IP client and server implementations. From it’s previous versions, library inherits a full blown stable support for XMPP protocol stack. In v3.0, support for HTTP protocol stack was also added.

At the heart of every protocol stack sits a Core stack. It contains all the building blocks for everything that we aim to do with Jaxl library. Both XMPP and HTTP protocol stacks are written on top of the Core stack. Infact the source code of protocol implementations knows nothing about the standard (inbuilt) PHP socket and stream methods.

Source code on GitHub

Examples

Documentation

Group and Mailing List

Create a bug/issue

Read why v3.x was written and what traffic it has served in the past.

PHP Code, Setup and Demo of Jaxl boshchat application

Jaxl 2.0 bosh support allow web developers to write real time web applications within minutes, without having any pre-requisite knowledge about the XMPP protocol itself. In this blog post, I will walk you through setup and demo of an XMPP based web chat application using Jaxl library.

Get the code
Follow the following steps to download and install this sample web application on your systems:

  • Clone the development branch of Jaxl library
    root@ubuntu:~/git# git clone git@github.com:abhinavsingh/JAXL.git
    root@ubuntu:~/git# cd JAXL/
    root@ubuntu:~/git/JAXL#

    If you are not familiar with git, simply visit JAXL@github, click Download Source and extract under ~/git/JAXL directory on your system

  • Once inside Jaxl source directory, build the latest development package
    root@ubuntu:~/git/JAXL# ./build.sh
    building...
  • Install Jaxl library (view installation detail and options)
    root@ubuntu:~/git/JAXL# ./build.sh install
    uninstalling old package...
    installing...

Setup web chat application
Jaxl library is default installed under /usr/share/php/jaxl folder. Application code for our web chat application can be found under /usr/share/php/jaxl/app/boshchat folder.

Follow these steps to setup web chat application on your system:

  • I assume you have http://localhost/ configured on your local web server and it runs out of /var/www folder. Create following symlinks:
    root@ubuntu:~/git/JAXL# cd /var/www
    root@ubuntu:/var/www# ln -s /usr/share/php/jaxl/app/boshchat/boshchat.php index.php
    root@ubuntu:/var/www# ln -s /usr/share/php/jaxl/app/boshchat/jaxl.ini jaxl.ini
    root@ubuntu:/var/www# ln -s /usr/share/php/jaxl/env/jaxl.js jaxl.js
    root@ubuntu:/var/www# ln -s /usr/bin/jaxl jaxl.php

    Edit/Remove #!/usr/bin/env php inside jaxl.php if it causes any problem on your system.

  • Open and edit jaxl.ini
    define('JAXL_BOSH_COOKIE_DOMAIN', false);
  • I assume you have access to XMPP over Bosh enabled jabber server. Ejabberd users can verify this by hitting http://localhost:5280/http-bind in the browser
  • Open and edit index.php
    define('BOSHCHAT_ADMIN_JID', 'admin@localhost');

    All messages sent using this web chat application will be routed to BOSHCHAT_ADMIN_JID

Ready for the demo
To run this example web chat application, visit http://localhost in your browser window. Enter a username/password already registered on your jabber server and press connect.

Login as BOSHCHAT_ADMIN_JID using a desktop client, so that you can receive messages sent from the browser on your desktop client.

Below is a screenshot when I logged in as “abhinavsingh” from browser and BOSHCHAT_ADMIN_JID was set to “jaxl@jaxl.im”:

Releasing Jaxl 2.0 – Object oriented XMPP framework in PHP

After months of restructuring the Jaxl library, I am pleased to announce Jaxl 2.0, an object oriented XMPP framework in PHP for developing real time applications for browsers, desktops and hand held devices.

What’s new in Jaxl 2.0?

  • A lot of structural changes has been done from the previous version to make it more scalable, robust, flexible and easy to use
  • Library now provides an event mechanism, allowing developers to register callbacks for various xmpp events in their application code
  • Use integrated BOSH support to write real time web applications in minutes
  • More than 10 new implemented XMPP extensions (XEP’s) added
  • Development hosting moves to github, stable releases available at google code

Documentation for Jaxl users
Below is a list of getting started documentation for XMPP app developers:

Implemented XEP’s
A lot of new XEP’s has been implemented and packaged with Jaxl 2.0. Developers can use Jaxl event mechanism to implement new XEP’s without knowing the working of other core parts of the library.

Below is a list of released implemented XEP with Jaxl 2.0:

Documentation for project contributors
For developers interested in contributing to the Jaxl project, here is a list of insight documentation to get you started:

  • Jaxl core workflow and architecture (coming soon)
  • How to implement new XMPP extensions using Jaxl (coming soon)

Useful Links
For live help and discussion join jaxl@conference.psi-im.org chat room

Setting Nginx, PHP Fastcgi and XCache on a new Ubuntu

Recently, because of a mandatory VPS move I had an opportunity to migrate all my sites from apache to nginx. My old box was in a messy state and setting up a new box from scratch was always going to be fun. Here in this post, I will walk you through all the steps that helped me migrate seamlessly. Specially, how did I setup the new box ensuring zero downtime on the sites.

Ensuring zero downtime while migration:
By the time I will pin up various pieces on my new vps box, I didn’t want my site visitors to see an under-maintenance page. To ensure zero downtime, I usually follow these steps:

  • Setup the new vps with nginx, php-fastcgi, etc as described later in the post
  • To verify the setup on new vps, edit the local host file depending upon your operating system
    /private/etc/hosts (mac)
    /etc/hosts (ubuntu)
    C:WindowsSystem32driversetchosts (windows)
    

    Go ahead and add the following host entry:

    99.198.122.216 abhinavsingh.com

    where, 99.198.122.216 is my new vps ip address and abhinavsingh.com is a vhost configured to handle by nginx on my new vps

  • Now, whenever I visit http://abhinavsingh.com in my browser, my local machine will point it to my new vps box. However, all other visitors will still be served by apache on old vps.
  • After verifying the setup, I simply remove previously added host setting on my local box and update the DNS settings for my site at godaddy.

To start with, just add up the required host setting on your local system.

Installing Nginx and configuring vhosts:
Follow these steps to install nginx webserver:

  • Update and upgrade apt-get and install nginx
    sudo apt-get update
    sudo apt-get upgrade
    sudo apt-get install nginx
  • Configure vhost for nginx by creating a file /etc/nginx/sites-available/mysite.com as follows:
    server {
            listen   80;
            server_name  mysite.com;
            access_log  /var/log/nginx/mysite.access.log;
    
            root   /var/www/mysite;
            index  index.php index.html index.htm;
    
            location / {
            }
    }
  • Enable vhost by creating a symlink as follows:
    cd /etc/nginx/sites-enabled
    ln -s /etc/nginx/sites-available/mysite.com mysite.com
    sudo /etc/init.d/nginx restart
  • Assuming you have configured your local host file correctly, try visiting http://mysite.com and your browser will take it to the new vps

Setting up php-fastcgi and xcache:
Here are the steps to configure php-fastcgi and how to ensure php-fastcgi is up and running even after system reboot. We will also configure xcache for better performance.

  • sudo apt-get install php5-cgi php5-cli php5-xcache
  • Download php-fastcgi default config and place it at /etc/default/php-fastcgi
  • Download php-fastcgi init.d script and place it at /etc/init.d/php-fastcgi
  • Add php-fastcgi init.d as startup script
    update-rc.d -f php-fastcgi defaults
  • Update following fields inside /etc/php5/conf.d/xcache.ini:
    xcache.admin.user = "admin"
    xcache.admin.pass = "pass"
    xcache.size  =  128M
    xcache.count = 4

    xcache.count should ideally be equal to cat /proc/cpuinfo |grep -c processor

  • Setup xcache admin interface:
    cd /var/www
    ln -s /usr/share/xcache/admin xcache
  • Update /etc/php5/cgi/php.ini as per your requirements and start php-fastcgi process
    sudo /etc/init.d/php-fastcgi start
  • Visit xcache admin panel http://vps_ip_address/xcache

Stitching php-fastcgi and nginx vhosts:
Now lets enable php for vhosts configured with nginx:

  • Download nginx fastcgi param config file and place it at /etc/nginx/fastcgi.conf
  • Update /etc/nginx/sites-available/mysite.com with following config:
    location ~ .php$ {
                    fastcgi_pass    127.0.0.1:9000;
                    fastcgi_index   index.php;
                    fastcgi_param   SCRIPT_FILENAME /var/www/mysite$fastcgi_script_name;
                    include         /etc/nginx/fastcgi.conf;
            }
    
  • Restart nginx and we are done

Here we complete the vps setup and vhost configurations. Verify the new vps setup and once satisfied update site’s DNS settings. Another challenge involving migration from apache to nginx includes rewriting apache .htaccess rewrite rules for nginx. However, I will keep that for another post.

Writing your first facebook chat bot in PHP using Jaxl library

Today facebook officially announced availability of it’s chat through jabber/xmpp clients. This is a big win for XMPP, with almost 400 million new probable users adding into XMPP club. In this post, I will demonstrate how to connect to facebook chat servers using Jaxl client library in PHP. It can further be used to make custom chat bots for facebook.

Creating your first facebook chat bot:
Follow the steps to successfully run a facebook chat bot:

  1. Download Jaxl or checkout latest from trunk
    svn checkout http://jaxl.googlecode.com/svn/trunk/ jaxl-read-only
  2. Edit the configuration file config.ini.php as follows:
      // Set an enviornment
      $env = "prod";
    
      $key = array("prod"=>array("user"=>"facebook_username",
                                 "pass"=>"facebook_password",
                                 "host"=>"chat.facebook.com",
                                 "port"=>5222,
                                 "domain"=>"chat.facebook.com"
                                ),
  3. Run from command line:
    abhinavsingh@abhinavsingh-desktop:/jaxl$ sudo php index.php
    OSType: Linux, Registering shutdown for SIGINT and SIGTERM
    OpenSSL: Enabled for CLI
    Attempting DIGEST-MD5 Authentication...
    Starting Session...
    Requesting Feature List...
    Requesting Roster List...
    Setting Status...
    Done
    

Try to send a message to your running chat bot and you shall receive a default message back from the bot saying “Hi, Thanks for your message”.

See further sample codes and explaination on how to build a full fledged gaming chat bots under xmpp category.

MEMQ : Fast queue implementation using Memcached and PHP only

Memcached is a scalable caching solution developed by Danga interactive. One can do a lot of cool things using memcached including spam control, online-offline detection of users, building scalable web services. In this post, I will demonstrate and explain how to implement fast scalable queues in PHP.

MEMQ: Overview
Every queue is uniquely identified by it’s name. Let’s consider a queue named “foo” and see how MEMQ will implement it inside memcached:

  • Two keys namely, foo_head and foo_tail contains meta information about the queue
  • While queuing, item is saved in key foo_1234, where 1234 is the current value of key foo_tail
  • While de-queuing, item saved in key foo_123 is returned, where 123 is the current value of key foo_head
  • Value of keys foo_head and foo_tail start with 1 and gets incremented on every pop and push operation respectively
  • Value of key foo_head NEVER exceeds value of foo_tail. When value of two meta keys is same, queue is considered empty.

MEMQ: Code
Get the source code from GitHub:
http://github.com/abhinavsingh/memq

<?php

	define('MEMQ_POOL', 'localhost:11211');
	define('MEMQ_TTL', 0);

	class MEMQ {

		private static $mem = NULL;

		private function __construct() {}

		private function __clone() {}

		private static function getInstance() {
			if(!self::$mem) self::init();
			return self::$mem;
		}

		private static function init() {
			$mem = new Memcached;
			$servers = explode(",", MEMQ_POOL);
			foreach($servers as $server) {
				list($host, $port) = explode(":", $server);
				$mem->addServer($host, $port);
			}
			self::$mem = $mem;
		}

		public static function is_empty($queue) {
			$mem = self::getInstance();
			$head = $mem->get($queue."_head");
			$tail = $mem->get($queue."_tail");

			if($head >= $tail || $head === FALSE || $tail === FALSE)
				return TRUE;
			else
				return FALSE;
		}

		public static function dequeue($queue, $after_id=FALSE, $till_id=FALSE) {
			$mem = self::getInstance();

			if($after_id === FALSE && $till_id === FALSE) {
				$tail = $mem->get($queue."_tail");
				if(($id = $mem->increment($queue."_head")) === FALSE)
					return FALSE;

				if($id <= $tail) {
					return $mem->get($queue."_".($id-1));
				}
				else {
					$mem->decrement($queue."_head");
					return FALSE;
				}
			}
			else if($after_id !== FALSE && $till_id === FALSE) {
				$till_id = $mem->get($queue."_tail");
			}

			$item_keys = array();
			for($i=$after_id+1; $i<=$till_id; $i++)
				$item_keys[] = $queue."_".$i;
			$null = NULL;

			return $mem->getMulti($item_keys, $null, Memcached::GET_PRESERVE_ORDER);
		}

		public static function enqueue($queue, $item) {
			$mem = self::getInstance();

			$id = $mem->increment($queue."_tail");
			if($id === FALSE) {
				if($mem->add($queue."_tail", 1, MEMQ_TTL) === FALSE) {
					$id = $mem->increment($queue."_tail");
					if($id === FALSE)
						return FALSE;
				}
				else {
					$id = 1;
					$mem->add($queue."_head", $id, MEMQ_TTL);
				}
			}

			if($mem->add($queue."_".$id, $item, MEMQ_TTL) === FALSE)
				return FALSE;

			return $id;
		}

	}

?>

MEMQ: Usage
The class file provide 3 methods which can be utilized for implementing queues:

  1. MEMQ::is_empty – Returns TRUE if a queue is empty, otherwise FALSE
  2. MEMQ::enqueue – Queue up the passed item
  3. MEMQ::dequeue – De-queue an item from the queue

Specifically MEMQ::dequeue can run in two modes depending upon the parameters passed, as defined below:

  1. $queue: This is MUST for dequeue to work. If other optional parameters are not passed, top item from the queue is returned back
  2. $after_id: If this parameter is also passed along, all items from $after_id till the end of the queue are returned
  3. $till_id: If this paramater is also passed along with $after_id, dequeue acts like a popRange function

Whenever optional parameters are passed, MEMQ do not remove the returned items from the queue.

MEMQ: Is it working?
Add following line of code at the end of the above class file and hit the class file from your browser. You will get back inserted item id as response on the browser:

var_dump(MEMQ::enqueue($_GET['q'], time()));

Lets see how cache keys looks like in memcached:

abhinavsingh@abhinavsingh-desktop:~$ telnet localhost 11211
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

get foo_head
VALUE foo_head 1 1
1
END

get foo_tail
VALUE foo_tail 1 1
2
END

get foo_1
VALUE foo_1 1 10
1265540583
END

get foo_2
VALUE foo_2 1 10
1265540585
END

MEMQ: Benchmark
Below are the benchmarking results for varying load:

  1. Queuing performance: 697.18 req/sec (n=1000, c=100) and 258.64 req/sec (n=5000, c=500)
  2. Dequeue performance: 641.27 req/sec (n=1000, c=100) and 242.87 req/sec (n=5000, c=500)

MEMQ: Why and other alternatives
There are several open source alternatives which provide a lot more scalability. However, MEMQ was written because my application doesn’t expect a load in order of 10,000 hits/sec. Listed below are a few open source alternatives for applications expecting high load:

  1. ActiveMQ: A reliable and fast solution under apache foundation
  2. RabbitMQ: Another reliable solution based on AMQP solution
  3. Memcacheq: A mash-up of two very stable stacks namely memcached and berkleyDB. However, it’s installation is a bit tricky.

MEMQ: Mantra and Customization
At the base MEMQ implementation can be visualized as follows:

There is a race between two keys in memcached (foo_head and foo_tail). Both are incremented on every dequeue and queue operation respectively. However, foo_tail is strong enough and never allows foo_head to exceed. When value of keys foo_tail and foo_head are equal, queue is considered empty.

The above code file still doesn’t include utility methods like MEMQ::total_items etc. However, writing such methods should be pretty easy depending upon your application needs. Also depending upon your application requirement, you should also take care of overflowing integer values.

JAXL BOSH Demo: IM chat client for all WordPress blogs

Have you ever wished of a wordpress plugin capable of providing a facebook style chat bar on your blog post. In this blog post, I will lay down the details of how Jaxl‘s bosh support comes in handy for building such browser based real time application. Specifically, I will explain how I achieved building a plugin for my wordpress blog. If everything goes perfect over next few weeks, this plugin might be submitted in wordpress plugin’s directory.

Jaxl BOSH Support Framework
Jaxl BOSH support comprise of three main parts:

  • jaxl.jquery.js: JQuery extension written for Jaxl bosh support
  • jaxl4bosh.class.php: Connection manager in PHP
  • jaxl UI: Integrated UI framework for changing your application skin on the fly. Your application skin can be a simple facebook style chat bar (as on this page) or chesspark style whole html page

jaxl.jquery.js is responsible for initiating and maintaining a connection between the browser and the PHP connection manager. While jaxl4bosh.class.php implements the BOSH protocol and maintain a persistent connection with the jabber server.

jaxl.jquery.js provide a few basic methods like:

  • jaxl.connect: Call for initiating the connection
  • jaxl.sendMessage: Call for sending a message to other jid’s
  • jaxl.ping: Call to maintain the connection and gather any incoming data
  • jaxl.disconnect: Call for disconnecting

jaxl4bosh.class.php provide wordpress style filter/hooks which can be used to modify every incoming and outgoing messages.

  • jaxl_pre_connect: Call to perform initialization before jaxl connects to jabber server
  • jaxl_post_connect: Call to perform shutdown after jaxl is connected to jabber server
  • jaxl_send_message: Call to perform actions on outgoing messages from jaxl
  • jaxl_recv_message: Call to perform actions on incoming messages to jaxl
  • jaxl_send_presence: Call to perform actions on outgoing presence from jaxl
  • jaxl_recv_presence: Call to perform actions on incoming presence from jaxl
  • jaxl_pre_disconnect: Call to perform initialization before jaxl disconnects to jabber server
  • jaxl_post_disconnect: Call to perform shutdown after jaxl is disconnected to jabber server

Jaxl and WordPress
Using Jaxl bosh support require you to only edit the configuration file. Here are the config variables:

        // JAXL config
        define('JAXL_BOSH_HOST', 'localhost');
        define('JAXL_BOSH_SERVER', 'localhost');
        define('JAXL_BOSH_URL', 'http://localhost:7070/http-bind/');
        define('JAXL_ADMIN_JID', 'admin@localhost');

You can configure Jaxl to use any of the available public xmpp services. However, I choose to host my own jabber server for my blog.

JAXL_ADMIN_JID is the admin jid to which Jaxl should route all incoming messages, added specifically for wordpress related requirement. PHP connection manager can be extended to route different chat sessions to different admins.

jaxl_recv_message handler is used to embed smiley’s and youtube videos by parsing the incoming chat messages.
jaxl-bosh-support-hook-demo-youtube-smiley

A few other hooks like jaxl_post_connect are used to notify JAXL_ADMIN_JID about the newly connected user.

Admin Screen
Below is a screen shot of how an admin desktop will look like while chatting with his site visitors:
Admin-screenshot-jaxl-bosh-support

Let me know if you are having any issues chatting using the chat bar at the bottom of the page. Code and installation might be buggy at times, and would appreciate any help from you on it.

Get real time system & server load notification on any IM using PHP and XMPP

There are various system and server related information which server administrators always need to have as soon as possible, infact I must say in real time. There are several open and closed source softwares in the market which can generate almost real time notifications for you. Most famous one being Nagios. In this blog post I will discuss, how to generate real time system notifications using PHP and XMPP. Specifically, I will present sample script using Jaxl (Jabber XMPP Client Library) for generating real time system load notifications, which can be received using any Instant Messengers.

/proc/loadavg
We will be using system /proc/loadavg file to get real time system load information. If you are unaware about this file, here is in brief how this file is helpful to us:

sabhinav:~# cat /proc/loadavg
0.22 0.12 0.09 1/68 12621

where first three columns measure the CPU and IO utilization of last one, five and 10 minute periods. The fourth column shows the number of currently running processes and the total number of processes. The last column displays the last process ID used.

jaxl4serveradmins.class.php
We will be using Jaxl PHP client library for handling the XMPP part. jaxl4serveradmins.class.php is an extension to Jaxl, providing various server administration helper function. Below is the code for server administration extension:

  include_once("xmpp.class.php");

  define('JAXL_SERVER_ADMIN', 'mailsforabhinav@gmail.com');
  define('JAXL_SERVER_LOAD_POLL_INTERVAL', 10);

  class JAXL extends XMPP {

    function eventMessage($fromJid, $content, $offline = FALSE) {
    }

    function eventPresence($fromJid, $status, $photo) {
    }

    function eventNewEMail($total,$thread,$url,$participation,$messages,$date,$senders,$labels,$subject,$snippet) {
      // Not used here. See jaxl4gmail.class.php for it's use case
    }

    function setStatus() {
      // Set a custom status or use $this->status
      $this->sendStatus($this->status);
      print "Setting Status...n";
      print "Donen";

      $this->addJob(JAXL_SERVER_LOAD_POLL_INTERVAL, array($this, 'parseServerLoad'));
    }

    function parseServerLoad() {
      $loadavg = file_get_contents('/proc/loadavg');
      $this->sendMessage(JAXL_SERVER_ADMIN, $loadavg);
    }

  }

I have utilized addJob() method provided by Jaxl library, using which you can specify a callback to be called after every N seconds (in short a periodic cron). Here we add a periodic job to be runned every JAXL_SERVER_LOAD_POLL_INTERVAL seconds. parseServerLoad() method is called as the callback function.

$this->addJob(JAXL_SERVER_LOAD_POLL_INTERVAL, array($this, 'parseServerLoad'));

To keep the demo simple, I am simply sending the content of /proc/loadavg file as a message to server admins.

    function parseServerLoad() {
      $loadavg = file_get_contents('/proc/loadavg');
      $this->sendMessage(JAXL_SERVER_ADMIN, $loadavg);
    }

Running it for your servers:
Follow the following steps to get this started on your server (only Unix, no Windows):

  • Checkout from Jaxl trunk
    sabhinav:~# sudo svn checkout http://jaxl.googlecode.com/svn/trunk/ jaxl-read-only
  • Enter checked out directory
    sabhinav:~# cd jaxl-read-only
  • Enter your server admin IM contact details
    sabhinav:~# sudo vim config.ini.php
    define('JAXL_SERVER_ADMIN', 'webmaster@foobar.com');
  • Enable server administration extension
    sabhinav:~# sudo vim index.php
    include_once("jaxl4serveradmins.class.php"); // include_once("jaxl.class.php");
  • Wroom Wroom, start Jaxl
    sabhinav:~# sudo php index.php
    Starting TLS Encryption...
    Attempting PLAIN Authentication...
    Starting Session...
    Requesting Feature List...
    Requesting Roster List...
    Setting Status...
    Done
    

Tail the jaxl log file in case you are facing any difficulties in the setup.

sabhinav:~# tail -f log/logger.log

You should also consider adding /proc/ directory under open_basedir in php.ini file.

Is it working?
If all is well configured server admins will start getting notifications every 10 seconds which is default value for JAXL_SERVER_LOAD_POLL_INTERVAL.
Jaxl4serveradmins.class.php example screenshot for system load

Writing custom notifications
Above I demonstrate how we can use XMPP and PHP to generate real time system notification. However, you may want to modify parseServerLoad() method to send notifications only when the server load exceeds a certain value. You may also want to add other methods which can notify you of various System and Server level parameters in a similar fashion. Below are a few useful system administration commands:

sabhinav:~# free -m
sabhinav:~# vmstat 1 20

Is it really real time?
Since, parseServerLoad() method polls for /proc/loadavg file every 10 seconds, this is not exactly real time. However you can configure JAXL_SERVER_LOAD_POLL_INTERVAL to make it poll faster. You can also use libevent extension in PHP to make it real time in real sense.

Do let me know if you write any interesting functionality, I will be more than happy to include it as a part of current extension.