Jaxl 2.0 Core classes, available methods and directory structure

In this blog post we will dig deep into the core of Jaxl 2.0 – An XMPP framework written in PHP. Specifically, we will go through Jaxl core directory structure. Towards the end we will get familiar with various core classes and their available methods (e.g. $jaxl->sendMessage()), that developers can use in their XMPP applications.

Core Directory Structure
Now that you have the source code, lets get familiar with the Jaxl directory structure. Downloaded source code consists of following 5 directories:

  • xmpp: Contain core stack which implements XMPP rfc’s. All files follow naming convention like xmpp.*.php
  • core: Contains core stack which manages the library workflow. Also provides an xpath based XML parser, an event mechanism and various other utilities to the framework. All files follow naming convention like jaxl.*.php
  • xep: Contains implemented XMPP extensions (XEP’s). All files follow naming convention like jaxl.XEP-NUMBER.php
  • env: Contains Jaxl main() file jaxl.php, Jaxl core configuration file jaxl.conf and application environment setup file jaxl.ini. For bosh application developers jaxl.js is a must include from this directory.
  • app: Contains example applications which comes packed with Jaxl library

Core Classes and Available Methods
Below is a detailed list of all the core classes and available methods in developer land space:

JAXL
This class is located inside core/jaxl.class.php and extends base XMPP class. Following is a list of methods available:

  • __construct($config=array()) : Constructor accepts following configuration parameters. Passed parameters will overwrite corresponding jaxl.ini values:
    $config = array(
        'user'=>'', // JAXL_USER_NAME
        'pass'=>'', // JAXL_USER_PASS
        'host'=>'', // JAXL_HOST_NAME
        'port'=>'', // JAXL_HOST_PORT
        'domain'=>'', // JAXL_HOST_DOMAIN
        'component'=>'', // JAXL_COMPONENT_HOST
        'logPath'=>'', // JAXL_LOG_PATH
        'logRotate'=>'', // false or second in which to rotate log
        'logLevel'=>'', // JAXL_LOG_LEVEL
        'pidPath'=>'', // JAXL_PID_PATH
        'boshHost'=>'', // JAXL_BOSH_HOST
        'boshPort'=>'', // JAXL_BOSH_PORT
        'boshSuffix'=>'', // JAXL_BOSH_SUFFIX
        'resource'=>'', // connecting user resource identifier
        'streamTimeout'=>'', // connecting stream timeout
        'sigh'=>'', // boolean to forcible enable/disable sigh term
        'dumpStat'=>'', // false or numeric specifying second after which to dump stat
    );
  • auth($type) : Performs authentication with the jabber server. DIGEST-MD5, PLAIN, X-FACEBOOK-PLATFORM and ANONYMOUS are the supported auth $type
  • setStatus($status=FALSE, $show=FALSE, $priority=FALSE, $caps=FALSE) : Update the status of connected jabber user. Pass $caps=TRUE for sending entity capability information while setting connected user status.
  • subscribe($toJid)
  • subscribed($toJid)
  • unsubscribe($toJid)
  • unsubscribed($toJid)
  • getRosterList($callback=FALSE) : Fetch roster list for the connected user. See example usage inside echobot application.
  • addRoster($jid, $group, $name=FALSE)
  • updateRoster($jid, $group, $name=FALSE, $subscription=FALSE)
  • deleteRoster($jid)
  • sendMessage($to, $message, $from=FALSE, $type=’chat’)
  • sendMessages($to, $from, $child, $type)
  • sendPresence($to, $from, $child, $type)
  • $jaxl->requires($class) : It is an alternative for jaxl_require($class, $jaxl).
  • $jaxl->xml->xmlize($xml) : Use this method to convert raw XML string into an array.
  • $jaxl->log($log, $level) : Use this method for logging purposes

JAXLPlugin
This class is located inside core/jaxl.plugin.php. Following is a list of methods available:

  • add($hook, $callback, $priority=10) : Register callback on available hooks
  • remove($hook, $callback) : Un-register callback on a previously registered hooks using add method

JAXLCron
This class is located inside core/jaxl.cron.php. Use this call methods to run periodic background jobs. Following is a list of methods available:

  • add($callback, $interval) : $callback methods is called every $interval second
  • delete($callback, $interval) : Removes a previously registered cron job

JAXLUtil
This class is located inside core/jaxl.util.php. Following is a list of methods available:

  • isWin() : Window OS detection, return bool
  • getTime()
  • getBareJid($jid)
  • splitJid($jid)
  • curl($url, $type=’GET’, $headers=FALSE, $data=FALSE, $user=FALSE, $pass=FALSE)

More methods might get added in future and will be updated here.

Using available XEP methods
Once have included required XEP class inside your application code, either by using jaxl_require('JAXLxxxx', $jaxl) or by calling $jaxl->requires('JAXLxxxx'), you can start using the available methods inside included XEP class as follows:

$jaxl->JAXLxxxx('methodName', $param1, $param2, ....);

e.g. If you want to call joinRoom methods of Multi-User Chat XEP-0045, you can do so by calling

$jaxl->JAXL0045('joinRoom', $jid, $roomJid.'/'.$nick, $history, $seconds)

. DO-NOT call the method like JAXL0045::joinRoom(…)

Writing a command line XMPP bot (echobot) using Jaxl 2.0

In this blog post, we will write a sample XMPP bot (echobot) using Jaxl 2.0. In turn we will introduce ourselves to some of the basic functionality we can do using Jaxl e.g. fetching roster list, subscribing and unsubscribing to a user presence, etc. We will also focus on how to use XMPP extensions (XEP’s) inside our echobot code. Specifically, we will make use of XEP-0085 (chat state notification), XEP-0203 (delayed delivery) and XEP-0092 (software version) in our sample echobot application.

Echobot source code:
This sample echobot application comes packaged with Jaxl 2.0. If you have already read Installation, Usage guide and Running example apps, you might have even run this sample application.

Alternately, browse and download the sample source code from github echobot app files

Coding with Jaxl 2.0:
Every XMPP application developed using Jaxl 2.0, MUST have a jaxl.ini environment setup file inside your project directory. For example, packaged echobot sample application contains jaxl.ini which setup necessary Jaxl environment for our echobot application.

If you are developing an application from scratch, copy sample packaged jaxl.ini into your project folder:

cp /usr/share/php/jaxl/env/jaxl.ini /my/app/directory/jaxl.ini

and update JAXL_BASE_PATH and JAXL_APP_BASE_PATH with Jaxl installation path and your application directory path respectively.

Before we go on to write our echobot application code logic, lets see how an XMPP application code written using Jaxl 2.0 will generally look like:

<?php

        // Initialize Jaxl Library (#1)
        $jaxl = new JAXL();

        // Include required XEP's (#2)
        jaxl_require(array(
                'JAXL0085', // Chat State Notification
                'JAXL0092', // Software Version
                'JAXL0203'  // Delayed Delivery
        ), $jaxl);

        // Sample Echobot class (#3)
        class echobot {
                function startStream() {}
                function doAuth($mechanism) {}
                function postAuth() {}
                function getMessage($payloads) {}
                function getPresence($payloads) {}
        }
        $echobot = new echobot();

        // Add callbacks on various xmpp events (#4)
        JAXLPlugin::add('jaxl_post_connect', array($echobot, 'startStream'));
        JAXLPlugin::add('jaxl_get_auth_mech', array($echobot, 'doAuth'));
        JAXLPlugin::add('jaxl_post_auth', array($echobot, 'postAuth'));
        JAXLPlugin::add('jaxl_get_message', array($echobot, 'getMessage'));
        JAXLPlugin::add('jaxl_get_presence', array($echobot, 'getPresence'));

?>

Lets break down the above applications code structure (note the #1, #2, #3, #4 markers in the above code)

  • #1 – Create a new Jaxl instance inside your application. By doing so Jaxl core functionality and other utilities are made available inside your application code. You can also pass parameters while initializing Jaxl instance
    $jaxl = new JAXL(array(
            'user'    =>    'username',
            'pass'    =>    'password',
            'host'    =>    'talk.google.com',
            'domain' =>    'gmail.com',
            'port'    =>    5222
    ));

    Passed parameters will overwrite the values specified inside jaxl.ini file

  • #2 – Include required XMPP extensions (XEP’s) inside your application code. jaxl_require is a special method which makes sure that no Jaxl core class loads twice inside a running Jaxl instance.

    To include an implemented XEP inside your application code simply use:

    jaxl_require('JAXL0203', $jaxl);

    where 0203 is the XEP number for Delayed Delivery extension, which will help our echobot know if an incoming message is an offline message. If you wish to include more than one XEP inside your application code, simply pass the list of XEP’s as an array:

    jaxl_require(array(
    	'JAXL0085',
    	'JAXL0092',
    	'JAXL0203'
    ), $jaxl);

    where 0085 is xep number for Chat state notification extension and 0092 is the xep number for Software Version extension.

    Since version 2.1.0, jaxl_require MANDOTORY accepts Jaxl instance which require core classes, in this case $jaxl. It helps Jaxl core to keep a track of required core classes for every Jaxl instances in a multiple-instance application.

  • #3 – Now that we have Jaxl core and required XEP’s in our application environment, it’s time to write our application code logic. Application code MUST have methods which are called back by the Jaxl core when specific xmpp events occur during your application run time. Optionally, Jaxl core can pass parameters to these methods during callbacks.
  • #4 – In the final step, we will register callbacks for necessary xmpp events using JAXLPlugin class add() method inside our application logic. Syntax:
    JAXLPlugin::add($hook, $callback);

    In this example, we want to receive callbacks in our application code for following available hooks and events:

    1. jaxl_post_connect: After Jaxl has opened stream socket to the jabber server
    2. jaxl_get_auth_mech: When Jaxl have information about supported auth mechanisms by the jabber server
    3. jaxl_post_auth: After Jaxl finish authenticating the bot with the jabber server
    4. jaxl_get_message: When a new message stanza is received by Jaxl
    5. jaxl_get_presence: When a new presence stanza is received by Jaxl

Writing application logic:
Till now we have the registered callbacks for various xmpp events, it’s time to catch these callbacks inside our echobot class and implement the required functionality of our application. Below is an explanation for some of the important pieces inside echobot class:

  • startStream() method is called when jaxl_post_connect event occurs. For our application we will simply send XMPP start stream by calling $jaxl->startStream()
  • doAuth($mechanism) method is called when jaxl_get_auth_mech event occurs in Jaxl core. Jaxl core passes list of supported auth mechanism by the jabber server. Proceed with a preferred auth type by calling $jaxl->auth() method
  • postAuth() is called after Jaxl library has finished authenticating our application bot with the jabber server
  • getMessage($payloads) gets all new messages as they are received by Jaxl core
  • getPresence($payloads) gets all new presence as they are received by Jaxl core

Running Echobot:
Enter your application directory (/usr/share/php/jaxl/echobot). It MUST contain jaxl.ini, open and edit connecting echobot username, password and jabber host. Then from command line run echobot as follows:

[email protected]:/usr/share/pear/jaxl/app/echobot# jaxl echobot.php
== 5617 == [[2010-08-03 10:37:21]] Socket opened to the jabber host jaxl.im:5222 ...
== 5617 == [[2010-08-03 10:37:22]] Performing Auth type: DIGEST-MD5
== 5617 == [[2010-08-03 10:37:28]] Auth completed...

Jaxl 2.0 – Installation, Usage guide and Example apps

This blog post provides detailed instructions on how to download and setup Jaxl 2.0 for quick XMPP application development using PHP. We will also see how to run XMPP bots using Jaxl command line utility (now available by just typing jaxl on the terminal).

Get the source code
Jaxl 2.0 development version source code is available at github.

  • For better experience download latest stable tarball from google code
  • The development version of Jaxl is hosted here at Github, have fun cloning the source code with Git. If you are not familar with Git just use the download button to get a tarball.
    [email protected]:~/git# git clone git://github.com/abhinavsingh/JAXL.git

Warning: the development source code is only intended for people that want to develop Jaxl or absolutely need the latest features still not available on the stable releases.

Installation on *nix Systems
Extract the downloaded tarball and enter source directory. The available build.sh file will help us installing Jaxl library at a preferred location on our system. Type ./build.sh help to view help instructions:

[email protected]:~/git# cd JAXL
[email protected]:~/git/JAXL# ./build.sh help

Build file will default install Jaxl library core under /usr/share/php/jaxl and Jaxl command line at /usr/bin/jaxl. Open build script, edit PACKAGE_INSTALL_PATH and PACKAGE_BIN_PATH to configure installation paths.

Issue following commands to setup Jaxl library core and Jaxl command line utility:

[email protected]:~/git/JAXL# mkdir /usr/share/php/jaxl
[email protected]:~/git/JAXL# ./build.sh
building...
[email protected]:~/git/JAXL# ./build.sh install
uninstalling old package...
installing...
[email protected]:~/git/JAXL# touch /var/log/jaxl.log
[email protected]:~/git/JAXL# chown www-data /var/log/jaxl.log
[email protected]:~/git/JAXL# touch /var/run/jaxl.pid
[email protected]:~/git/JAXL# chown www-data /var/run/jaxl.pid

/var/log/jaxl.log is default log file for Jaxl applications and /var/run/jaxl.pid saves the process id (pid) of running Jaxl instances.

Usage guide
Now that we have setup Jaxl on our system, lets verify package installation by firing jaxl command line utility on the terminal:

[email protected]:~/git/JAXL# jaxl
Missing ini file...

If you get “Missing ini file” message, you have successfully verified package installation. This message is shown when current working directory doesn’t have jaxl.ini file, which is required by Jaxl cli utility before it can connects to a jabber server.

Running sample applications
Build script installs a sample application under /usr/share/php/jaxl/app/echobot directory. This directory contains two files namely:

  • echobot.php: Contains our echobot application code
  • jaxl.ini: It is application specific Jaxl configuration file

Open and update the following section inside jaxl.ini:

        // Connecting bot details
        define('JAXL_USER_NAME', 'username');
        define('JAXL_USER_PASS', 'password');

        // Connecting jabber server details
        define('JAXL_HOST_NAME', 'jabber.org');
        define('JAXL_HOST_PORT', 5222);
        define('JAXL_HOST_DOMAIN', 'jabber.org');

Now run the echobot from using jaxl cli utility:

[email protected]:/usr/share/php/jaxl/app/echobot# jaxl echobot.php
== 2946 == [[2010-08-02 14:37:53]] Socket opened to the jabber host jabber.org:5222 ...
== 2946 == [[2010-08-02 14:37:57]] Performing Auth type: DIGEST-MD5
== 2946 == [[2010-08-02 14:38:02]] Auth completed...

2946 is the process id of current running Jaxl instance. Same value can be found inside /var/run/jaxl.pid. Also tail the Jaxl log file for debug information:

[email protected]:~/git/JAXL# tail -f /var/log/jaxl.log
== 2946 == [[2010-08-02 14:38:02]] [[XMPPSend]] 123
chatOnline using Jaxl (Jabber XMPP Library in PHP)1

[[XMPPSend]] tells us that following XMPP packet was send by the Jaxl instance running with pid 2946. Also, total 123 bytes were transmitted over the socket.

Proceed to Writing your first command line bot using Jaxl for detailed explanation of the sample echobot application or if you are interested in building real-time web applications read Setup and Demo of Jaxl boshchat application

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 [email protected] chat room

Introducing WP-Chat :: XMPP Chat plugin for WordPress

WP-Chat plugin embeds Jaxl IM (Instant Messenger for the web) for wordpress blogs. It runs across all major browsers and built upon XMPP protocol. It is a hosted solution from Jaxl.im empowering real time communication between you and your site visitors. It expects no software or hardware pre-requisites from your site servers or users. Above all it’s free!

Overview:

  • Supports for all major browser including Firefox, Chrome, Safari and IE
  • Embeddable on all blogs, forums, personal, social and enterprise sites
  • Built using XMPP protocol (backbone for facebook and google chats)
  • Hosted dashboard for site admins and IM users
  • Pluggable and Skinnable using developer api
  • Connect with you desktop IM clients (e.g. Pidgin, PSI, …)

History:
In two of my previous post (Introducing MemChat and Jaxl BOSH Demo), I discussed and demoed a very early version of WP Chat plugin. In past 3 months, work has been done to make WP Chat generic enough so that it can be embedded across all kind of blogs, forums, social, personal and enterprise level websites. As of today, the product is named as “Jaxl IM (Instant Messenger for the web)” and made available as “WP-Chat” for the wordpress users.

Setting up ejabberd 2.1.x development environment on Ubuntu

apt-get provide a convenient way of installing ejabberd on Ubuntu distributions. However, if you are an erlang developer and looking to write custom ejabberd modules, you might want to install ejabberd from the source code.

Checkout ejabberd source
To start with lets grab the ejabberd 2.1.x branch source code:

  • sudo apt-get install git-core
  • git clone git://git.process-one.net/ejabberd/mainline.git ejabberd
  • cd ejabberd
  • git checkout -b 2.1.x origin/2.1.x
  • cd src

Installing pre-requisites
Lets setup necessary pre-requisites before compiling ejabberd source code:

  • sudo apt-get install build-essential
  • sudo apt-get install automake autoconf
  • sudo apt-get install erlang erlang-manpages
  • sudo apt-get install libexpat1-dev zlib1g-dev libssl-dev

Compiling ejabberd source code
Compiling and installing is dead simple:

  • ./configure
  • make
  • sudo make install

Setting up administration account
By now we have ejabberd server setup on our ubuntu box. Lets setup the admin account:

  • sudo ejabberdctl start
  • sudo ejabberdctl register admin localhost password
  • sudo vim /etc/ejabberd/ejabberd.cfg
  • Add following configurations if not already present:
    {acl, admin, {user, "admin", "localhost"}}.
    {loglevel, 5}. %% Log level while development
  • sudo ejabberdctl restart
  • Visit ejabberd admin panel: http://localhost:5280/admin
  • When prompted enter username as [email protected] and the password you chose above while registering admin account

Resolving startup errors
You might see a few error reports in logs or elsewhere while starting ejabberd server:

  • /sbin/ejabberdctl: 340: cannot create //var/lock/ejabberdctl/ejabberdctl-1: Directory nonexistent
  • =ERROR REPORT==== 2010-03-29 21:53:03 ===
    C(<0.995.0>:ejabberd_captcha:331) : The option captcha_cmd is not configured, but some module wants to use the CAPTCHA feature.
  • =INFO REPORT==== 2010-03-29 21:53:03 ===
    I(<0.780.0>:ejabberd_rdbms:37) : ejabberd has not been compiled with relational database support. Skipping database startup.

Here is how you can resolve the above errors:

  • sudo mkdir /var/lock/ejabberdctl/ejabberdctl-1
  • Add following line in ejabberd.cfg
    {captcha_cmd, "/lib/ejabberd/priv/bin/captcha.sh"}.

    Replace /lib/ejabberd/priv/bin/captcha.sh with path to /ejabberd/tools/captcha.sh

Getting started with ejabberd development
Below are links to a few useful resources to get you started with erlang and ejabberd module development:

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:
    [email protected]:/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.

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', [email protected]');

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', [email protected]');
  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', [email protected]');
  • 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.

Get lyrics for any song using XMPP and PHP right into your IM – Add [email protected]

XMPP is soon finding it’s way into real time applications other than just chat. I have combined JAXL (Jabber XMPP client library written in PHP) and the API from lyricsfly.com to build a real time chat bot which can assist you with lyrics for any song. You can start using it by simply adding [email protected] to your IM account (e.g. Gtalk, Jabber etc). In this blog post, I will explain in brief the working of lyricsfly bot and how you can integrate XMPP into your own application.

Try out [email protected]
Follow the following steps to get the bot working for you:

  • Login to your gtalk account using any of the IM available
  • Press Add Contact
  • Add [email protected] as your chat buddy
  • Send a chat message in following format “Song Title – Song Artist” e.g. “one – metallica”
  • You should see something like this: lyricsfly@gtalkbots.com Demo for "one-metallica"

Working of [email protected] with Jaxl
Here is in brief the working of lyricsfly bot using Jaxl client library:

  • When someone sends a message like “one – metallica” to the bot, eventMessage() method is called inside jaxl.class.php
  • eventMessage then extracts the song title and artist name from the message using PHP explode. Filter the title and artist names for allowed characters.
  • eventMessage also calls lyricsfly API and fetch the lyrics. Finally it sends the lyrics as message to requester.
  • eventMessage also uses memcached to cache the lyrics. It decreases both response time and load on lyricsfly servers
  • Bot also keeps a count of number of queries from a particular user. Since it is still under development, currently there is a limit on number of lyrics you can fetch in a single day.

Making your own custom bot

  • Checkout latest from the trunk
    sabhinav$ svn checkout http://jaxl.googlecode.com/svn/trunk/ jaxl-read-only
  • Edit config file with your bot username, password and jabber servers
  • Run from command like
    php index.php
  • To customize the bot modify eventMessage and eventPresence methods of Jaxl class inside jaxl.class.php

For a full fledged running bot example code, edit index.php and include jaxl4dzone.class.php instead of jaxl.class.php and re-run the bot.

Have fun and enjoy singing songs along with the lyrics.