Several aspects of CAXL are different enough from what you find in typical libraries that it is helpful to describe them at the beginning. The CAXL team has found that these aspects can be confusing to developers who are new to CAXL, and we will be building on these concepts throughout the book. Some of these building blocks come from the fact that CAXL is a library for XMPP interactions, and some of them have emerged from the CAXL team's design for the library itself. Let's dive right in.
XMPP is a technology for instant messaging, presence, and other forms of real-time communication. Because of their real-time nature, XMPP libraries need to handle a number of XMPP "primitives".
XMPP is a distributed client-server technology. In XMPP, both servers and clients have addresses based on the domain name system (DNS). For historical reasons, an XMPP address is called a JabberID or "JID". A server's JID is a domain name, such as example.com
or cisco.com
. A user's JID looks like an email address, such as user@example.com
. One distinctive addition to XMPP addressing is the concept of a "resource", which is a specific session or device that is currently associated with a user's account, such as user@example.com/mobile
or user@example.com/web
. (A JID of the form localpart@domainpart/resource
is known as a "full JID", whereas a JID of the form localpart@domainpart
is known as a "bare JID".)
As mentioned in Chapter 1, the traditional method by which a client connects to a server in XMPP is an XML stream over a long-lived TCP socket. The HTTP binding that CAXL uses, called BOSH, emulates long-lived TCP sockets by sharing XML streams using HTTP long-polling techniques. Whether the TCP binding or the HTTP binding is used, an XMPP client has a stateful session on an XMPP server, which lasts as long as the client is connected (whether directly over TCP or virtually over BOSH). The states associated with a session might include presence information (e.g., "away" or "do not disturb") and some XMPP details that we'll explore later in the book.
One of the distinctive features of XMPP is presence: the ability to know when entities on the network are available for communication. At the level of a session, a server knows when clients are available by the mere existence of the session itself. At the level of a contact list or "roster", a client knows when other entities are available because the user of the client has been authorized to receive presence information about those entities (typically other users).
In a more general sense, an online client is always available for incoming data it might receive from the server, such as instant messages or presence information from the user's contacts. This model is quite different from, say, HTTP, where a browser requests data (via HTTP GET) and then receives it. In XMPP, once a client is online it might receive data at any time, and it needs to be ready to handle that data in real time. (Web developers might be familiar with the XMLHttpRequest API, which somewhat blurs the lines between the more synchronous world of HTTP and the more asynchronous world of XMPP; in a sense, CAXL combines the best of HTTP and XMPP by providing a web-friendly API for XMPP interactions.)
The core XMPP protocol, specified in RFC 6120, includes three kinds of "stanza", which function as communication primitives: <message/>
, <presence/>
, and <iq/>
. As you might imagine, CAXL has three distinct classes for these stanza kinds, named Message
, Presence
, and IQ
.
<message/>
stanza is used to send one-to-one IM messages, notifications, information within textual chatrooms, and the like. Typically it is a "fire-and-forget" mechanism and a reply is not necessarily expected. Message stanzas can contain a wide variety of payloads, including plaintext bodies, XHTML formatted text, and other, more specialized payloads (including custom data for specific applications).<presence/>
stanza is used to send presence notifications about the availability of a client and receive presence notifications about the availability state of other entities. Presence stanzas are also used to manage presence subscription states by requesting subscriptions, approving or denying subscription requests, and cancelling existing subscriptions.
<iq/>
stanza (short for "info/query") provides more structured interactions, similar to HTTP. An IQ stanza of type "get" is similar to an HTTP GET and requests the receipt of information from the server or from another entity on the network. An IQ stanza of type "set" is similar to an HTTP PUT or POST and creates or updates information on the server or another entity. A reply to an IQ stanza of type "get" or "set" is mandatory, and consists of an IQ stanza of type "result" or "error". We will see many examples of IQ-based interactions throughout the book.Just as XMPP enables asynchronous communication, CAXL assumes that interactions between the client and the server (or between the client and other entities on the network) will also be asynchronous. Beginning programmers might expect to send some data to the server and then wait for a response, as in the following pseudocode:
request = prepare(); response = send_and_wait(request); handle(response);
In CAXL, we don't wait and we don't block while we're waiting (in fact, CAXL doesn't even let you do that). Instead, when we send something off to another entity, we create a callback function that is invoked when we receive a response, as in the following pseudocode:
request = prepare(); send_and_listen(request, function(response) { handle(response); });
We will see endless examples of this pattern throughout the book.
From the beginnings of JavaScript, the goal was to add interactivity to web pages: the script lies dormant until the user does something on the page, thereby triggering an event. (There also are non-user-generated events, such as the load
event triggered when the page is loaded.)
CAXL adds a whole range of communication-related events to this interactivity model, because in CAXL many events are triggered when the script (i.e., the XMPP client) receives data from the XMPP server.
In CAXL, your script can create a new event, register for an event, and trigger an event (for which other scripts or other parts of the current script might be registered).
To create a new event on an object of type jabberwerx.JWModel
, your code calls the applyEvent(eventName)
method. This creates a new event and returns a jabberwerx.EventNotifier
object.
To register for an event, you use the event(eventName)
method on objects of type jabberwerx.JWModel
, which returns the associated jabberwerx.EventNotifier
for an existing event. There are two methods on the jabberwerx.EventNotifier
object:
bind(callback)
: register a callback method which is invoked when the event triggers. The callback method is passed an jabberwerx.EventObject
.bindWhen(selector, callback)
: similar to bind()
but with the additional selector (jQuery string or method) which is a filter to determine whether to trigger the event or notTo trigger an event, your code uses the trigger()
method on the jabberwerx.EventNotifier
object
Because XMPP is a technology for communication, almost everything we want to interact with servers and users and clients and chatrooms and data sources and so on has a JabberID (and sometimes a secondary identifier called a node more about that later). Anything that's addressable on the network might be, in CAXL terms, an Entity. Thus, for example, each of the contacts in a user's contact list or roster is an Entity. So is a chatroom that a user joins, and so is each occupant in the chatroom.
Sometimes, entities are also grouped together into buckets called EntitySets. Thus a user's roster is an EntitySet, consisting of all the user's contacts. Similarly, collectively the occupants in a chatroom also form an EntitySet (which is related to, but distinct from, the Entity that is the chatroom itself).
If you think of an Entity as a JID or information about a JID, you won't go far wrong in CAXL.
© 2012 Cisco Systems, Inc. All rights reserved.