How to write External Jabber Components in PHP using Jaxl library?

Jabber Component Protocol (XEP-0114) documents how XMPP protocol can be used to communicate between servers and “external” components over the Jabber network. XMPP components “bind” to a domain, usually a sub-domain of the main XMPP service, such as service.example.org.

All incoming stanzas addressed to that domain (to='service.example.org') or to entities on that domain (to='user@service.example.org') will be routed to your Jaxl (Jabber XMPP Library) based code. In this blog post, I will demonstrate a sample external jabber component bot written in PHP using Jaxl library.

Refer Jaxl Installation, Usage guide and Example apps if you are new to Jaxl. Demonstrated component bot code can be obtained from Jaxl@github.

Using Jabber Component Protocol
Include Jaxl implementation of XEP-0114 in your application code to setup necessary environment for using Jabber component protocol. Here is how this can be done at the top of your application code:

        // Initialize Jaxl Library
        $jaxl = new JAXL(array(
                'component' => JAXL_COMPONENT_HOST,
                'port' => JAXL_COMPONENT_PORT
        ));

        // Include required XEP's
        jaxl_require('JAXL0114', $jaxl); // Jabber Component Protocol

Register callback for XMPP events
Above we have setup the necessary environment for writing external Jabber component bots. Next we register callback for necessary XMPP events inside our componentbot class.

        // Sample Component class
        class componentbot {

        }

        // Add callbacks on various event handlers
        $componentbot = new componentbot();
        JAXLPlugin::add('jaxl_pre_handshake', array($componentbot, 'doAuth'));
        JAXLPlugin::add('jaxl_post_handshake', array($componentbot, 'postAuth'));
        JAXLPlugin::add('jaxl_get_message', array($componentbot, 'getMessage'));

Component bot class
Finally, lets complete the missing pieces inside componentbot class.

        // Sample Component class
        class componentbot {

                function doAuth() {
                        $jaxl->log("Going for component handshake ...", 1);
                        return JAXL_COMPONENT_PASS;
                }

                function postAuth() {
                        $jaxl->log("Component handshake completed ...", 1);
                }

                function getMessage($payloads) {
                        global $jaxl;

                        // echo back
                        foreach($payloads as $payload) {
                                $jaxl->sendMessage($payload['from'], $payload['body'], $payload['to']);
                        }
                }

        }

Configure, Setup and Run
If you have a local “ejabberd” installed, add following lines inside ejabberd.cfg to make example component bot to work:

  {5559, ejabberd_service, [
                          {host, "component.localhost", [{password, "pass"}]}
                           ]},

Update jaxl.ini if you choose to have different password, port or host name above:

        // Connecting jabber server details
        define('JAXL_HOST_NAME', 'localhost');
        define('JAXL_HOST_DOMAIN', 'localhost');

        // Component bot setting
        define('JAXL_COMPONENT_HOST', 'component.'.JAXL_HOST_DOMAIN);
        define('JAXL_COMPONENT_PASS', 'pass');
        define('JAXL_COMPONENT_PORT', 5559);

Finally, run from command line:

root@ubuntu:~/usr/share/php/jaxl/app/componentbot# jaxl componentbot.php
[15008] 2010-08-24 01:40:03 - Socket opened to the jabber host localhost:5559 ...

Tail jaxl.log for details:

[15008] 2010-08-24 01:40:04 - Going for component handshake ...

[15008] 2010-08-24 01:40:04 - [[XMPPSend]] 63
<handshake>4d6c2e762d5ba5dca2cbd3a90a4deeb6a6fa0838</handshake>

[15008] 2010-08-24 01:40:05 - [[XMPPGet]]
<handshake/>

[15008] 2010-08-24 01:40:05 - Component handshake completed ...

Log into your Ejabberd with a client and send a message to anything@component.localhost – You should receive an instant response back – congratulations!