By DJ Adams
Price: $39.95 USD
£28.50 GBP
Cover | Table of Contents | Colophon
<presence from='john@company-b.com/Desk'
to='jim@company-a.com/home'>
<status>Online</status>
<priority>2</priority>
</presence>
<presence from='john@company-b.com/Desk'
to='jim@company-a.com/home'>
<status>Online</status>
<priority>2</priority>
</presence>
<message type='chat' from='jim@company-a.com/home'
to='john@company-b.com'>
<thread>01</thread>
<body>Hey John, have you seen the latest story on Megacorp earnings?</body>
</message>
<message type='chat' to='jim@company-a.com/home'
from='john@company-b.com/Desk'>
<thread>01</thread>
<body>No, where is it?</body>
</message>
<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>
<message to='john@company-b.com' from='alert@stocks.company-b.com'> <subject>ACMH Fallen below 250p</subject> <body>ACME Holdings price 248p as at 10:20am today</body> </message>
Net::Jabber
library, which provides a high-level API to many Jabber-related functions
such as handling the connection to the server (this is via another
library that Net::Jabber uses—XML::Stream), authentication, events,
and all the mechanisms to parse and create Jabber traffic.
#!/usr/bin/perl
use Net::Jabber qw(Client);
use strict;
# List of addressees for our reminder
our @addressees;
# What we want to send
my $reminder = $ARGV[0] or die "No reminder!";
# Connect to our Jabber server
my $c= Net::Jabber::Client->new();
$c->Connect('hostname' => 'yak',
'port' => 5222);
# Authenticate
$c->AuthSend('username' => 'reminder',
'password' => 'secret',
'resource' => 'reminder');
# Set handler to deal with presence packets
# that might (will) be pushed to us (we're
# not interested in any other type of packet)
$c->SetCallBacks('presence' => \&handle_presence);
# Send out our own presence, and run an
# event loop for up to 5 seconds to
# catch any packets pushed to us
$c->PresenceSend();
$c->Process(5);
# Create a new message with our reminder text
my $m = Net::Jabber::Message->new();
$m->SetBody($reminder);
# Send the message to each of the addressees collected
# in the handle_presence() subroutine
foreach my $jid (@addressees) {
$m->SetTo($jid);
$c->Send($m);
}
# Disconnect from the Jabber server and exit
$c->Disconnect;
exit(0);
# Deal with presence packets
sub handle_presence {
my ($sid, $presence) = @_;
# Get the presence
my $show = $presence->GetShow() || 'online';
# If the user is around, add to addressee list
push @addressees, $presence->GetFrom()
if $show eq 'online' or $show eq 'chat';
}
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.
<message/>,
<iq/>, and
<presence/>.
<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.
<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.
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.
|
Element
|
Tag
|
Types
|
|---|---|---|
|
Message
|
<message>
|
normal, chat, groupchat, headline, error |
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>
<message/>,
<iq/>, and <presence/>,
can carry these attachments.
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.
<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>
GET /home.html HTTP/1.0 is the request,
and everything else, starting with HTTP/1.1 200 OK,
is the 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> ...
GET and the specification
of what to retrieve (the /home.html document), and it
shows us what is returned in response.
<iq/>.
<iq/> element to effect the IQ request/response
model.
<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.
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.
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.
http://www.gnu.org)
are recommended if you don't already have them installed.
http://www.jabber.org; the
1.4.1 version is available in the downloads area:
http://download.jabber.org/dists/1.4/final/jabber-1.4.1.tar.gz
http://download.jabber.org.
yak:/usr/local# mkdir jabber
yak:/usr/local# groupadd jabber yak:/usr/local# useradd -g jabber -d /usr/local/jabber jabber yak:/usr/local# passwd jabber Changing password for jabber Enter the new password (minimum of 5, maximum of 127 characters) Please use a combination of upper and lower case letters and numbers. New password: ******** Re-enter new password: ******** Password changed. yak:/usr/local# chown jabber:jabber jabber yak:/usr/local#
yak:/usr/local# su - jabber yak:~$ tar xzf jabber-1.4.1.tar.gz yak:~$ cd jabber-1.4.1/ yak:~/jabber-1.4.1$
<host/>
parameter specifies the
Jabber server's hostname. As delivered, the jabber.xml
configuration has this set to localhost:
<host><jabberd:cmdline flag="h">localhost</jabberd:cmdline></host>
yak:~/jabber-1.4.1$ ./jabberd/jabberd
yak:~/jabber-1.4.1$ ./jabberd/jabberd -h yak
<log id='elogger'>
<host/>
<logtype/>
<format>%d: [%t] (%h): %s</format>
<file>error.log</file>
<stderr/>
</log>
<!-- <stderr/> -->Or redirect STDERR to /dev/null:
yak:~/jabber-1.4.1$ ./jabberd/jabberd -h yak 2>/dev/null
yak:~/jabber-1.4.1$ ./jabberd/jabberd -h yak 2>/dev/null &
<log id='elogger'>
<host/>
<logtype/>
<format>%d: [%t] (%h): %s</format>
<file>error.log</file>
<stderr/>
</log>
<log id='rlogger'>
<host/>
<logtype>record</logtype>
<format>%d %h %s</format>
<file>record.log</file>
</log>
c2s.
s2s.
<jabber/>.
The opening tags for each of these chunks are as follows:
<service id="sessions">
<xdb id="xdb">
<service id="c2s">
<log id="elogger">
<log id="rlogger">
<service id="dnsrv">
<service id="jud">
<service id="s2s">
<service id="conf">
<io>
sessions component, described by the configuration
XML shown in Example 4-8 and shown in diagram form
in Figure 4-5, provides Session Management
features for users (the word "users" is employed in the widest possible
sense—a user could be a person or a script) connecting with Jabber
clients, through XML streams identified
with the jabber:client stream namespace.
<service id="sessions">
<host><jabberd:cmdline flag="h">yak</jabberd:cmdline></host>
<jsm xmlns="jabber:config:jsm">
<filter>
<default/>
<max_size>100</max_size>
<allow>
<conditions>
<ns/>
<unavailable/>
<from/>
<resource/>
<subject/>
<body/>
<show/>
<type/>
<roster/>
<group/>
</conditions>
<actions>
<error/>
<offline/>
<forward/>
<reply/>
<continue/>
<settype/>
</actions>
</allow>
</filter>
<vCard>
<FN>Jabber Server on yak</FN>
<DESC>A Jabber Server!</DESC>
<URL>http://yak/</URL>
</vCard>
<register notify="yes">
<instructions>Choose a userid and password to register.</instructions>
<name/>
<email/>
</register>
<welcome>
<subject>Welcome!</subject>
<body>Welcome to the Jabber server on yak</body>
</welcome>
<!--
<admin>
<read>support@yak</read>
<write>admin@yak</write>
<reply>
<subject>Auto Reply</subject>
<body>This is a special administrative address.</body>
</reply>
</admin>
-->
<update><jabberd:cmdline flag="h">yak</jabberd:cmdline></update>
<vcard2jud/>
<browse>
<service type="jud" jid="jud.yak" name="yak User Directory">
<ns>jabber:iq:search</ns>
<ns>jabber:iq:register</ns>
</service>
<conference type="public" jid="conference.yak" name="yak Conferencing"/>
</browse>
</jsm>
<load main="jsm">
<jsm>./jsm/jsm.so</jsm>
<mod_echo>./jsm/jsm.so</mod_echo>
<mod_roster>./jsm/jsm.so</mod_roster>
<mod_time>./jsm/jsm.so</mod_time>
<mod_vcard>./jsm/jsm.so</mod_vcard>
<mod_last>./jsm/jsm.so</mod_last>
<mod_version>./jsm/jsm.so</mod_version>
<mod_announce>./jsm/jsm.so</mod_announce>
<mod_agents>./jsm/jsm.so</mod_agents>
<mod_browse>./jsm/jsm.so</mod_browse>
<mod_admin>./jsm/jsm.so</mod_admin>
<mod_filter>./jsm/jsm.so</mod_filter>
<mod_offline>./jsm/jsm.so</mod_offline>
<mod_presence>./jsm/jsm.so</mod_presence>
<mod_auth_plain>./jsm/jsm.so</mod_auth_plain>
<mod_auth_digest>./jsm/jsm.so</mod_auth_digest>
<mod_auth_0k>./jsm/jsm.so</mod_auth_0k>
<mod_log>./jsm/jsm.so</mod_log>
<mod_register>./jsm/jsm.so</mod_register>
<mod_xml>./jsm/jsm.so</mod_xml>
</load>
</service>