JabChapter 2

From WikiContent

(Difference between revisions)
Jump to: navigation, search
(Component/Service Architecture)
Current revision (09:13, 7 October 2006) (edit) (undo)
(insert content template)
 
(One intermediate revision not shown.)
Line 1: Line 1:
 +
{{Content Programming Jabber}}
=Inside Jabber=
=Inside Jabber=
<br>Jabber has a number of features that are fundamental to its design philosophy.
<br>Jabber has a number of features that are fundamental to its design philosophy.
Line 391: Line 392:
Figure 2-1 shows the element traffic in a typical IQ-based conversation.
Figure 2-1 shows the element traffic in a typical IQ-based conversation.
 +
[[Image:Jab 0201.png|center|350 px|Element traffic in an IQ-based
 +
conversation]]
-
{{Figure|title=Element traffic in an IQ-based
+
<br>Example 2-5, Example 2-6,
-
conversation|image=0596002025-jab_0201.png}} Example 2-5, Example 2-6,
+
and Example 2-7 show typical uses of the <tt>&lt;iq/&gt;</tt> element to
and Example 2-7 show typical uses of the <tt>&lt;iq/&gt;</tt> element to
effect the IQ request/response model.
effect the IQ request/response model.
Line 556: Line 558:
client time queries.
client time queries.
<br>
<br>
- 
==Component/Service Architecture==
==Component/Service Architecture==

Current revision

Programming Jabber
Preface
1 - Getting started with Jabber
2 - Inside Jabber
3 - Installing the Jabber server
4 - Server Architecture and Configuration
5 - Jabber Technology Basics
6 - Jabber Namespaces
7 - User Registration and Authorization
8 - Using Messages and Presence
9 - Groupchat, : Components, and Event Models
10 - Pointers for Further Development
Appendix A
Appendix B
Colophon

Contents

Inside Jabber


Jabber has a number of features that are fundamental to its design philosophy. This design philosophy outlines Jabber as a much more flexible and generic solution to the original problem of connecting to disparate IM systems. These features give Jabber the potential to exist and act in the P2P (peer-to-peer, or person-to-person), A2P (application-to-person), A2A (application-to-application)—or in fact, any of the three-letter acronyms (TLAs) that have a 2 in the middle—spaces that have conversation at their core.

Understanding Jabber's features is fundamental to seeing how it fits into the bigger picture. In this chapter, we explore these features and discover in what ways Jabber is not simply a cross-IM mechanism. In this exploration, you'll get a feel for how capable Jabber is of being integrated into "conversational solutions."

In Part II of the book, we'll revisit each of these features and see how they can be used in many different programming scenarios.


XML-Based


Arguments abound for and against XML in the arena of data representation. XML is suited extremely well to Jabber, which is suited extremely well to XML. There are many reasons for this.

The alternatives for representing data in Jabber are binary and ASCII text. Binary? Well, perhaps binary data is more space efficient, but where is that advantage in the general scheme of things these days? Near the bottom of my list, anyway, especially as it's always at the cost of readability. ASCII? Well, yes, of course, ASCII is human readable, but since Jabber data flow consists of a series of conversationalchunks—independent constructions in their own right—we need some sort of boundary mechanism to separate these chunks. XML affords us a very nice way of packaging individual chunks of data and giving their content meaning and context. These individual chunks of information have structure too, and this structure doesn't require any fixed-length madness either; XML allows the chunks, or fragments, to bend and stretch as required, while still retaining their meaning.

This flexibility also comes in the form of extensibility. It's straightforward to add distinct "extensions" to a fragment in a way that does not compromise the integrity of that fragment and provides a structure to the extension added.

So why reinvent the wheel when there are tools that can be taken off the shelf to parse the data? There are many tried and tested XML libraries out there, and to be able to receive (from the parser) the Jabber data in a native format of your choice is a definite advantage.

Some of these arguments, concerning XML fragments and extensibility, will become clearer in Chapter 5. Until then, consider that Jabber makes good use of an XML feature called namespaces. (See http://www.w3.org/TR/REC-xml-names for more details.) Namespaces are used in XML to segregate, or qualify, individual chunks of data, giving tags a reference to which they belong. What the reference is, in many ways, is of secondary importance; the point is the delineation that allows us to manage content within an XML fragment that is logically divided into subfragments. Consider Example 2-1, which shows a section of the imaginary conversation from Chapter 1.


Qualifying a fragment extension with a namespace

|<message type='chat' from='jim@company-a.com/home' to='john@company-b.com/Desk'> <thread>01</thread> <body>Here's the link</body> <x xmlns='jabber:x:oob'> <url>http://www.megacorp.co.uk/earnings3q.html</url> <desc>Third Quarter Earnings for Megacorp</desc> </x> </message>


The main part of the fragment is the <message/> element containing the <thread/> and <body/> tags. The <message/> element is the "carrier" part of the fragment:


|<message type='chat' from='jim@company-a.com/home' to='john@company-b.com/Desk'> <thread>01</thread> <body>Here's the link</body> </message>


But the fragment has been embellished by an extension that is qualified by the jabber:x:oob namespace:


|<x xmlns='jabber:x:oob'> <url>http://www.megacorp.co.uk/earnings3q.html</url> <desc>Third Quarter Earnings for Megacorp</desc> </x>

The xmlns attribute of the <x/> tag declares that the tag and any children of that tag belong to, or are qualified by, the jabber:x:oob namespace. This namespace is used in Jabber to carry information about out-of-band (OOB) data: data that moves outside of the main client-server-client pathways. When a client sends a file directly to another client without sending that file via the server, this is said to be "out of band." See Section 6.3.8 in Chapter 6 for more details. This namespace is different from the namespace that qualifies the carrier <message/> tag and the other elements, <presence/> and <iq/>, that appear at the same level. The namespace that qualifies these tags is not explicitly specified as an xmlns attribute; rather, it is declared when the XML stream is established. It is over this XML stream that these elements flow. See Chapter 5 for more details on XML streams and namespaces.

The general point is that the jabber:x:oob-qualified extension is recognizable as an extension (by us and, more importantly, by the XML parser) and can be dealt with appropriately—we are likely to want to handle the information contained in the extension separately from the rest of the message.

So Jabber uses the extensible XML format to contain and carry data between endpoints.

"XML between endpoints"? That sounds rather generic to me—not something that's limited to providing an IM experience. Indeed, that's the whole idea.

"XML Router" is a moniker often used to describe Jabber by people who have made this logical leap. Remove the IM mantle, and underneath we find a system, an architecture, capable of being deployed to exchange and distribute all manner of XML-encoded data.


Asynchronous Nature


The exchange and distribution of information in real-world scenarios requires more than a synchronous (sequenced) request/response framework. In IM, people originate chat messages in a spontaneous and unpredictable manner (especially if there's beer involved). In a loose network of independent applications, messages originate on a similar "random" event basis. This asynchronous activity requires a design equally asynchronous in nature—and that is what Jabber has.

To allow for the generation, and more importantly the receipt, of messages in an asynchronous fashion, Jabber's programming model for client and server alike is an event-based one. An event-based programming model is nothing to be afraid of. In simple terms, it's just a loop that iterates either doing nothing in particular or doing something regularly (like checking for user input and acting upon it if required) while waiting for something (an event) to happen. In Jabber's case, it will be the receipt of an XML fragment. Depending on what type of fragment it is, a handler will be called to deal with that fragment. We saw a simple example of this in the Perl script in Chapter 1.

In all but the simplest deployment examples of Jabber, the event model pervades. We will see the model in action in Part II. And while we've reduced the receipt of chat messages to a rather dry and generic event idea, let's also look at some concepts that often go hand in hand with event-based messaging systems.


Store and Forward


Depending on circumstances, if you send a message to someone who's not currently connected, that message will be held and passed to the recipient when he does connect.

Likewise, in the wider context of application-to-application (A2A) or application-to-person (A2P) messaging, this store-and-forward concept is often useful in non-time-critical situations, such as a centralized logging mechanism in which the log-writing component might be temporarily unavailable or a workflow scenario in which an application passes a message to a supervisor for approval (in this case, the message would be similar to an email).


Queuing


Indeed, in the case of the recipient being offline and messages being handled by a store-and-forward mechanism, or simply where the recipient cannot handle the messages as fast as they arrive, the nature of the XML stream in which these message fragments are transmitted (see Chapter 5 for details) means that the messages are naturally queued, to be handled in the order that they arrive.



Message Receipt


In many cases, it's not much use sending a message to an application and having it queued or stored offline, without knowing whether the recipient actually did (eventually) receive and handle it. Jabber supports the concept of message receipt,whereby the sender can request an acknowledgment of receipt from the recipient. This request is sent along with the message itself. Support for message receiptexists in the form of a namespace—jabber:x:event—which is described in Section 6.3.6 in Chapter 6.

Messaging


We've been using the term "message" in quite a general sense, to represent data passing from one Jabber entity to another. In fact, as we'll see in Chapter 5, there are different sorts of messages—and each one has a certain role within the whole context of the Jabber protocol. They are sometimes referred to as elements, and there are three of them: <message/>, <iq/>, and <presence/>.


Note:
Actually, there are four, but the fourth,

<route/>, is only used in the server to route messages between the various components. More details on <route/> can be found in Section 4.1.2.3 in Chapter 4.


The <message/> element has five types—normal, chat, groupchat, headline, and error. The <iq/> and <presence/> elements also have types to distinguish and describe their usage and context. The <iq/> element has the types get, set, result, and error, while the <presence/> element has, among others, the types available and unavailable. Details can be seen in Table 2-1.

Furthermore, we already know that these elements can be extended using namespaces. Each element and type, and each of the pre-defined namespaces (those that begin jabber:) have been designed with specific scenarios in mind. An example of a headline<message/> element containing an extension qualified by a predefined namespace is shown in Example 2-3.


Jabber elements and types -
Element Tag Types
Message <message> normal, chat, groupchat, headline, error
IQ <iq> get, set, result, error
Presence <presence> available, unavailable, subscribe, subscribed, unsubscribe, unsubscribed, error

There's a certain amount of consideration to be given in this respect when designing our messaging solutions and applications; how should we employ the basic message types, and do we need to create our own custom extensions qualified by our own namespaces?

For the most part, the answers to these questions will depend on what sort of solution needs to be developed; however, it is also important to consider what support is already available off the shelf in the form of Jabber clients. This is especially the case if the application is A2P or P2A. These Jabber clients provide varying levels of features supporting the different elements and types. For example, WinJab (for Win32 platforms) and Jarl (cross-platform, written in Perl/Tk) both support the headline type <message/> and can display URL information, which typically comes attached to the message in a jabber:x:oob-qualified extension, in a useful way. If you're writing a news headline alert mechanism, for example, you may want to consider aiming development with a target of WinJab or Jarl in mind; the alternative is to develop your custom news headline viewer client. (Indeed, we do just that, in Section 9.4 in Chapter 9.)


Payload Carrier


Earlier in this chapter we saw how a basic message was embellished with a structured and parseable "attachment" in the form of a jabber:x:oob-qualified <x/> tag and its child tags:


|<x xmlns='jabber:x:oob'> <url>http://www.megacorp.co.uk/earnings3q.html</url> <desc>Third Quarter Earnings for Megacorp</desc> </x>


How does this actually work in practice? Well, partly by requirement, partly by convention:

  • All three of the elements, <message/>,

<iq/>, and <presence/>, can carry these attachments.

  • These attachments usually serve one of two purposes:
  1. To bring primary (or secondary) meaning to the element that contains it.
  2. To act as the driving force behind the element, such as that the

element really exists only to carry the attachment. This distinction is rather subtle, so let's look at a couple of examples.

Example 2-2 shows an attachment in the jabber:x:delay namespace. This works like a timestamp and in this context indicates when that presence element appeared—in other words, from what time Jim started on his break.


A jabber:x:delay extension adds meaning to a <presence/> element

|<presence from='jim@company-a.com/home' to='john@company-b.com'> <show>chat</show> <status>having a break from work</status> <priority>1</priority> <x xmlns='jabber:x:delay' from='jim@company-a.com/home' stamp='20010611T13:13:04'/> </presence>


Example 2-3 shows us a message element containing a URL attachment. In this case, the element serves to carry the URL attachment; there is not really any other purpose to it. Delivering the <message type='headline'/> carrier without the payload wouldn't make much sense.


A jabber:x:oob extension is the heart of a <message/> element

|<message type='headline' from='jabbercentral@news.company-b.com' to='john@company-b.com'> <x xmlns='jabber:x:oob'> <url>http://www.jabbercentral.com/news/view.php?news_id='989358658 </url> <desc> Tomorrow, May 9th, a meeting regarding the Jabber Foundation will be held. </desc> </x> </message>


The outermost tag of each attachment, by convention, is either
<x/> or <query/> although they can be any
valid XML tag name. The Jabber namespaces that are used to qualify
these <x/> and <query/> attachments
follow a convention, beginning with jabber:x: for those
qualifying the <x/> attachments, and jabber:iq:
for those qualifying the <query/> attachments.

The <x/> tag is used as a generic extension mechanism to add information to any of the Jabber elements, and <query/> is used to extend the <iq/> element.

The standard namespaces used in Jabber to qualify the <x/> and <query/> attachments are listed in Chapter 6. But we're not restricted to just those namespaces; we're free to build attachments qualified by custom namespaces, if we think that what we want to achieve isn't covered by anything out of the box. In this situation, there are two things to note:

  • The namespaces cannot begin jabber:. * The receiving

recipient of the extended element must be able to appropriately interpret the attachments.

Request/Response


The HyperText Transfer Protocol (HTTP) is a great example of a simple, effective request/response model used on the Web to request and respond to requests for HTML and other content. Example 2-4 shows a typical HTTP request/response pairing, where GET /home.html HTTP/1.0 is the request, and everything else, starting with HTTP/1.1 200 OK, is the response.


A typical HTTP request/response

|GET /home.html HTTP/1.0

HTTP/1.1 200 OK Date: Mon, 11 Jun 2001 13:43:13 GMT Server: Apache/1.3.12 (Unix) mod_perl/1.24 Last-Modified: Fri, 09 Jun 2000 13:47:56 GMT ETag: "8a69-6a-3940f58c" Accept-Ranges: bytes Content-Length: 306 Connection: close Content-Type: text/html

<html> <head> ...


It shows us the request verb GET and the specification of what to retrieve (the /home.html document), and it shows us what is returned in response.

While we've already seen that the Jabber protocol is asynchronous in nature, there is a similar request/response model available, too, which tends to the synchronous (i.e., first request, then response), although, unlike HTTP, the response is not guaranteed to immediately follow the request. Other unrelated Jabber fragments may be received in the stream in the time between request and response. This request/response model is called Info/Query, or IQ for short; the Jabber element employed in the implementation of this model is <iq/>.

This IQ model has many uses in providing Jabber's basic IM features. Figure 2-1 shows the element traffic in a typical IQ-based conversation.

Element traffic in an IQ-based conversation


Example 2-5, Example 2-6, and Example 2-7 show typical uses of the <iq/> element to effect the IQ request/response model.


A simple client version query via the IQ model

|SEND: <iq type='get' from='jim@company-a.com/home' to='mark@company-a.com/Laptop-7' id='v1'> <query xmlns='jabber:iq:version'/> </iq>

RECV: <iq type='result' to='jim@company-a.com/home' from='mark@company-a.com/Laptop-7' id='v1'> <query xmlns='jabber:iq:version'> <name>Jabber Instant Messenger</name> <version>1.7.0.14</version> <os>95 4.10</os> </query> </iq>


In Example 2-5 we see that the equivalent of HTTP's GET verb is the type='get' attribute of the <iq/> element and that the equivalent of what to get (/home.html) is our namespace specification in the <query/> tag.

Example 2-6 shows a two-stage request/response model. First, a query is made, using the IQ-get type with an ID of reg1 (the id attribute), to discover which fields are required for user registration. Then, the actual user registration attempt is made with the IQ-set (ID reg2). In this second stage, we can see a link with HTTP's POST verb, whereby data is sent along with the request.[1]


A multiple-phase IQ to register a user

|SEND: <iq type='get' id='reg1'> <query xmlns='jabber:iq:register'/> </iq>

RECV: <iq type='result' id='reg1'> <query xmlns='jabber:iq:register'> <instructions>Choose a name and pass to register.</instructions> <username/> <password/> </query> </iq>

SEND: <iq type='set' id='reg2'> <query xmlns='jabber:iq:register'> <username>helen</username> <password>tr0y</password> </query> </iq>

RECV: <iq type='result' id='reg2'/>


While HTTP is primarily a client/server protocol (although these words have less and less meaning in a peer-to-peer environment in which each participating entity can be both client and server), Example 2-5 shows that the IQ model can be used in a client-to-client (or server-to-server, or server-to-client, for that matter) context as well.

Example 2-7 shows how an IQ-based conversation can extend beyond the get ... result or set ... result model. It shows how the IQ model can be used to deliver results of a search request in stages.


Staggered response from IQ-based search request The search request:


|SEND: <iq type='set' to='ldap.company-a.com' id='801'> <query xmlns='jabber:iq:search'> <group>Support</group> </query> </iq>


The first part of the response is the first record found:


|RECV: <iq type='set' from='ldap.company-a.com' to='jim@company-a.com/home' id='801'> <query xmlns='jabber:iq:search'> <name>John Aston</name> <phone>4701</phone> <group>Support</group> </query> </iq>


The second record found:


|RECV: <iq type='set' from='ldap.company-a.com' to='jim@company-a.com/home' id='801'> <query xmlns='jabber:iq:search'> <name>Katie Smith</name> <phone>4711</phone> <group>Support</group> </query> </iq>


The last record found:


|RECV: <iq type='set' from='ldap.company-a.com' to='jim@company-a.com/home' id='801'> <query xmlns='jabber:iq:search'> <name>Jeremy Taylor</name> <phone>4702</phone> <group>Support</group> </query> </iq>


No more records have been found, and no more results are sent; instead, an "end marker," signified by the type='result' attribute, is sent:


|RECV: <iq type='result' from='ldap.company-a.com' to='jim@company-a.com/home' id='801'> <query xmlns='jabber:iq:search'/> </iq>


Because of the inherently asynchronous nature of Jabber, we need some way of matching the responses received with the original request. After all, if we were to fire off two requests almost simultaneously to ask for the local time on our server and on a client in New Zealand:


|SEND: <iq type='get' from='jim@company-a.com/home' to='piers@company-a.com/emacs'> <query xmlns='jabber:iq:time'/> <iq/>

SEND: <iq type='get' from='jim@company-a.com/home' to='company-a.com'> <query xmlns='jabber:iq:time'/> <iq/>


we might find that the responses come back out of sequence (in our view), because of the comparative network distances over which the two conversations must travel. First this:


|RECV: <iq type='result' to='jim@company-a.com/home' from='company-a.com'> <query xmlns='jabber:iq:time'/> <utc>20010611T17:59:13</utc> <tz>CET</tz> <display>Mon Jun 11 19:59:13 2001</display> </query> </iq>


and then this:


|RECV: <iq type='result' to='jim@company-a.com/home' from='piers@company-a.com/emacs'> <query xmlns='jabber:iq:time'/> <utc>20010611T17:59:14</utc> <tz>UTC+12</tz> <display>Tue Jun 12 06:59:14 2001</display> </query> </iq>


That's the reason for the id attribute in the examples earlier in this section. Between a request and a response, any id attribute value in the <iq/> element is preserved, allowing the requester to match up <iq/> request/response pairs. Using the id attribute, we can piece together related fragments of individual conversations, which in this case were a pair of client time queries.

Component/Service Architecture


The original problem for Jabber to solve was to provide bridges to different IM systems; the upshot of the solution was a server design that is ultimately as flexible as the imagination allows. Each of the IM bridges, or transports as they are often called, is a pluggable component; the Jabber server architecture, examined in detail in Chapter 4, is a component-based architecture. The standard Jabber server distribution comes with the components required to provide IM services, data storage, and server-to-server communication, for example. Each component is separately configurable and is made known to the server through the inclusion of that configuration into the main configuration structure.[2]

Components, also known as services, can be, to a large extent, platform agnostic. There are different methods by which components can connect to and interact with the Jabber server. One of these methods uses low-level Jabber library functions (in C) to bind the component (built in the form of a shared library) to the server. The other methods use either standard I/O (STDIO) in a process-spawning mechanism or TCP sockets.

Both the former library load method and the STDIO method require that the component runs on the same host as the Jabber server itself; this isn't in fact as restrictive as it sounds. As you'll find out in Chapter 4, it is possible to run multiple "instances" of a Jabber server across different hosts, each instance containing one or more components, in much the same way as, say, an SAP R/3 system can exist as multiple instances, each instance running on a separate host and providing different services (dialog, update, enqueue, message, background, gateway, spool) according to configuration.

Would it surprise you to learn that the binding fluid that flows between the Jabber server and components (and ultimately, of course, between Jabber clients and components) is XML? Of course not. In fact, it's the same XML that flows between Jabber clients and servers. There are extra message types that flow inside the server and between the components, including <route/>, <xdb/>, and <log/>. These message types are explained in Chapter 4.

The <message/>, <iq/>, and <presence/> elements can all flow to and from components—how a component handles or generates these elements reflects the purpose of that component. As we saw in the imaginary conversation in Chapter 1, components can also be addressed in the same way that other Jabber entities can be addressed:

  • As a whole, the JID is simply the name of the component, for example, stocks.company-a.com.
  • Using individual "users" as if they existed as separate entities within that component, for example, MEGC@stocks.company-a.com. A version of this imaginary conversation will become reality in Part II as we learn how to build our own components and attach them to the Jabber server.

Although components are addressed in the same way that clients are addressed, and the interaction is similar, there is one significant difference between writing or using a client (which could just as well be a stub connector for a service) and writing or using a component.

This difference is rooted in the Jabber server architecture and becomes clear when we consider the nature of how the components provide their services. Messages sent to a client entity that is not connected will be stored and forwarded to that entity the next time it connects and becomes available. This is because the client's connection is inherently hosted, or managed, by the standard component that provides IM services such as availability handling and message queuing. This is the Jabber Session Manager (JSM) component. All clients are handled this way and automatically partake of these features. All entities that connect over a stream with the jabber:client namespace are considered clients, and their XML-based interaction is handled by the JSM.

Because other components connected to the Jabber server are peer components to the JSM component, no availability or message queueing is available, as the JSM is designed to handle only client-connected entities. The components that connect as separate entities (i.e., those that aren't written as shared libraries) do so over a stream that is described by one of two namespaces, each beginning jabber:component:. See Chapter 4 and Chapter 5 for more details. To put it another way:

  • Send a message to a client that's not connected, and it will get stored until that client connects and becomes available again.
  • Send a message to a component that's not connected, and an error will occur.

From a philosophical standpoint, this is fair enough, as you're trying to address a (temporarily) nonexistent feature of the server. From a practical standpoint, this is not usually a problem unless you're in the habit of restarting your Jabber server to randomly connect or disconnect components.



Custom Clients


Earlier in this chapter, we discussed features of off-the-shelf clients such as WinJab and Jarl, clients that natively support the <message type='headline'/> element. Considering this, in combination with the features we know Jabber posesses and the solution potential that these features offer in presenting a wider deployment vista than IM services, we come to an interesting conclusion:

A Jabber client is a piece of software that implements as much of the Jabber protocol as required to get the job done.
What does this mean? WinJab supports a Jabber feature

called browsing (see later in this chapter); Jarl supports connections to the server via an HTTP proxy. Some clients merely support a limited subset of Jabber as we know it; for example, the sjabber client supports only the conferencing features of Jabber. (As a somewhat biased observer, I would, of course, call this "extremely focused.")

Our definition of a Jabber client deliberately omits any mention of a user interface (let alone a GUI!). Indeed, human interaction in a Jabber solution is only an assumption formed from the hangover of the IM idea. Various efforts are underway to use Jabber as a transport for A2A messaging—the Jabber As Middleware (JAM) project is one such effort (at http://mailman.jabber.org/listinfo/jamdev); an extension to one of the Perl libraries for Jabber (Jabber::Connection) to carry XML-RPC-encoded messages also exists (http://www.pipetree.com/jabber/jrpc/), which is shown in Section 10.2.7 in Chapter 10.

So, a Jabber client doesn't need to follow any particularly conventional model, except if you're developing an IM client, of course, and even then, flexibility and fitness for purpose are key. We will see this philosophy in action in Part II of the book, where we develop just enough Jabber client code to be able to connect to a server, authenticate, and deal with one-way alert-style messages. This is a key idea: you use as much, or as little, of what Jabber has to offer to build your solutions. This doesn't refer to the Jabber building blocks, but also to the existing software, in particular the clients. For example, if you wanted to develop a Jabber IM-based approval cycle workflow process, you could carry the approval data in a custom namespace-qualified message extension. In this case, you're going to have to build a custom client to interpret that extension. However, if you carry the approval data inside the body of a normal message, then you can more or less take your pick of ready-made clients. Furthermore, if you include URLs in the message body—which many graphical clients can render into an active link—you can easily bind in the power of existing web-based interactivity to complete the solution. We see an example of this in Section 10.4 in Chapter 10.



XML-RPC and SOAP


Realizing that if Jabber is an XML router that can carry XML-based custom payloads in synchronous and asynchronous modes, we can immediately start to imagine scenarios in which Jabber fits as a transport glue in other already established application domains.

The XML Remote Procedure Call (XML-RPC) specification and the Simple Object Access Protocol (SOAP) both formalize method calls and responses in XML. The XML-RPC specification describes the use of HTTP to carry those encoded calls and responses between endpoints, and SOAP can use HTTP too. What if we carry XML-RPC or SOAP payloads in Jabber? We immediately see the step-change increase in contextual richness; XML-RPC interactivity becomes part of a wider, all-encompassing conversation between applications and humans. Indeed, the breadth of that interactivity increases too; Jabber affords a network transparency across traditional firewalls and Network Address Translation (NAT) mechanisms that often defeat HTTP-based calls.

Traditional IM-based clients, applications using client stub libraries, and components can all make use of the power these technologies have to offer, without having to leave the comfort of their Jabber environment, which can serve as a messaging plasma between all sorts of entities and services.

We will look at embedding XML-RPC-encoded calls in Jabber messages in Section 10.2 in Chapter 10.



Browsing


The more pervasive Jabber becomes and the more it is used, the larger the world of entities grows. And therein lies the challenge. How can we identify, organize, and navigate these entities in any useful way? Within the relatively narrow world of IM, the entities that exist (the IM users) and the hierarchies and relationships that are formed between them (where the only hierarchies are in the form of user rosters) don't really present much of a problem; as all the entities are users, there's no classification problem, and there's no hierarchical navigation problem. But within a system that regards users, applications, and services as equals (the unifying concept of a JID is an especially powerful device here), we need to have some way of searching, traversing, discovering, and querying these entities that is consistent regardless of what those entities are. Enter Jabber Browsing.

Browsing was introduced in Version 1.4 of the Jabber server to solve some specific problems with service discovery: how clients found out about what services (say, what IM transports) were available from the Jabber server that they were connected to. The namespace that supported the original discovery mechanism (jabber:iq:agents) was found to be too restrictive and, more importantly, too specific. A more generic way of describing entities in the Jabber world was needed.

Browsing has since grown from that single problem space and can now be found in Jabber software everywhere. Want to find out what a user's client is capable of (so you can interact with it) or what it otherwise offers? Just browse to it. Want to find out what conference rooms currently exist on a particular conference service? Browse that service. Want to take a peek to see who's in one of the rooms? Navigate down one level to browse to the room (if this is permitted by that room).

There are four key elements that make browsing so flexible and so powerful:


Categorization
Browsing follows the MIME model in defining categories and
subcategories, but rather than content being categorized
(text/plain, image/png, and so on), the
categorization in browsing is of entities that can be browsed to.
Categories are used to describe users, services, agents, conferencing
mechanisms, applications, and so on. Within these categories, the
subcategories are used to make finer distinctions
(service/pager, conference/private,
user/device, and so on).
Identification
Every entity described in browsing is identifiable by a JID; the world
is homogenized, so to speak. The JID is the key to browsing navigation
as, when listed in a browse result as identifiation for an entity,
that JID can be used as the target of the next browse request.
Hierarchy
Browsing describes entities in the Jabber world. But the world isn't
flat—it's hierarchical! Relationships between entities are easily
established and described by placing browse information in
hierarchies. These hierarchies, these relationships, are represented
in XML. A typical browse response might contain descriptions of
entities on one or two levels. These levels can be navigated simply by
choosing the JID of the desired node and making a further browse
request, creating an instant "drill-down" method to access
information.
Discovery
It might be that the only information you have about any particular
entity is its JID. You've been passed the JID from someone else, or
you've found it when browsing a hierarchy of relationships. Browsing
to that entity allows you to find out more—to discover what
features and services it supports, through a list of namespaces
returned in response to that browse request. So, Jabber entities can
be classified, given identities, organized into hierarchies, and
navigated. What takes place from there is really up to the
imagination. But what is a Jabber entity? For the sake of
argument, let's say it's anything that has a JID. Does having a JID
presume having an IM user account with a Jabber server? Not
necessarily, as we'll see. So as long as we assign a JID to something
we wish to include in the Jabber world, most anything goes. In Section
10.3 in Chapter 10, we build an LDAP "reflector" service that enables
us to browse LDAP information from within our Jabber clients.

Browsing is a combination—a culmination even—of many of the Jabber features. Browsing is carried out in the context of the IQ request/response mechanism and uses a namespace-qualified payload to carry the data whose hierarchy is naturally expressed in XML. Browsing bridges, philosophically and technically, the distances between the Jabber and non-Jabber spaces.

Personal tools