📄 x5334.htm
字号:
</reminders>
<favorites xmlns='url:favourites'>
<fav url='http://dev.jabber.org'>Jabber DevZone</fav>
<fav url='http://www.scripting.com'>Scripting News</fav>
</favorites>
</query>
</iq></PRE
></P
><P
>would only result in the storage of the <TT
CLASS="LITERAL"
>cal:events</TT
>
chunk. The <TT
CLASS="LITERAL"
>url:favorites</TT
> chunk would be ignored.</P
><P
>In the 1.4.1 release of the Jabber server, the
<TT
CLASS="FILENAME"
>mod_xml</TT
> JSM module that services the
<TT
CLASS="LITERAL"
>jabber:iq:private</TT
> namespace has been extended to
allow this server-side storage to encompass nonprivate (i.e., publically
accessible) user data. The namespace in this case is, fittingly
<I
CLASS="EMPHASIS"
>not</I
> <TT
CLASS="LITERAL"
>jabber:iq:private</TT
>. It can
be anything you wish, provided that it doesn't encroach on the standard
Jabber namespace names—<TT
CLASS="LITERAL"
>jabber:*</TT
> and
<TT
CLASS="LITERAL"
>vcard-temp</TT
> are not allowed—however, anything else goes.
<A
NAME="AEN5813"
HREF="#FTN.AEN5813"
>[6]</A
></P
><P
>The idea of publically accessible data is just that; you can make
information available to your fellow Jabber users (share URLs, contact
lists, and so on). Of course, this sharing is only one way; you write and
others can only read. But how do they find out <I
CLASS="EMPHASIS"
>what</I
>
you've made available for them to read? The namespaces of any data stored
publically (i.e., any namespace except for <TT
CLASS="LITERAL"
>jabber:iq:private</TT
>)
are returned by the Jabber server acting on behalf of the user in response
to a <TT
CLASS="LITERAL"
>jabber:iq:browse</TT
> request to that user's JID.
<A
NAME="AEN5820"
HREF="#FTN.AEN5820"
>[7]</A
></P
><P
>Let's have a look at this in action. We'll also have a peek at how the storage
of the public and private information is structured in the user's spool file
on the server to understand how this works.
<A
NAME="AEN5823"
HREF="#FTN.AEN5823"
>[8]</A
>
In addition to the Father's Day event that was stored privately in the previous example,
we can also set some favorite URLs in a publically accessible namespace and
receive an acknowledgement of successful storage from the server:</P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq type='set' id='setfavs'>
<query xmlns='dj:public:favorites'>
<item url='http://dev.jabber.org'>Jabber DevZone</item>
<item url='http://www.scripting.com'>Scripting News</item>
</query>
</iq>
RECV: <iq type='result' from='dj@yak/Work' to='a1@yak/Work' id='setfavs'/></PRE
></P
><P
>Now, the relevant section of <TT
CLASS="LITERAL"
>dj@yak</TT
>'s spool file
on the server looks something like that shown in
<A
HREF="x5334.htm#JABTDG-CH-5A-EX-7"
>Example 5a-2</A
>.</P
><DIV
CLASS="EXAMPLE"
><A
NAME="JABTDG-CH-5A-EX-7"
></A
><P
><B
>Example 5a-2. Section of user's spool storage showing public and private data</B
></P
><P
><PRE
CLASS="SCREEN"
> ...
<foo xmlns='jabber:xdb:nslist' xdbns='jabber:xdb:nslist'>
<ns type='private'>cal:events</ns>
<ns>dj:public:favourites</ns>
</foo>
<reminders xmlns='cal:events' j_private_flag='1' xdbns='cal:events'>
<event date='20010617'>Father's Day</event>
</reminders>
<query xmlns='dj:public:favorites' xdbns='dj:public:favourites'>
<item url='http://dev.jabber.org'>Jabber DevZone</item>
<item url='http://www.scripting.com'>Scripting News</item>
</query>
... </PRE
></P
></DIV
><P
>There are a few things to note in this example:</P
><P
></P
><UL
><LI
><P
>The <TT
CLASS="LITERAL"
>jabber:xdb:nslist</TT
> namespace maintains a list
of namespaces containing information stored for private and public
reference.</P
></LI
><LI
><P
>The <TT
CLASS="LITERAL"
>private</TT
> namespaces are marked in this list with a
<TT
CLASS="LITERAL"
>type='private'</TT
> attribute.</P
></LI
><LI
><P
>There is an additional flag (<TT
CLASS="LITERAL"
>j_private_flag='1'</TT
>)
which is held as an attribute of each of the privately stored fragments.</P
></LI
><LI
><P
>Otherwise the information is stored exactly as it was set (additional
<TT
CLASS="LITERAL"
>xdbns</TT
> attributes related to the XDB storage mechanisms
notwithstanding).</P
></LI
></UL
><P
>The namespaces (<TT
CLASS="LITERAL"
><ns/></TT
> tags) in
the <TT
CLASS="LITERAL"
>jabber:xdb:nslist</TT
> qualified list are returned in
any browse request to that user:</P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq type='get' to='dj@yak'>
<query xmlns='jabber:iq:browse'/>
</iq>
RECV: <iq type='result' to='sabine@yak/Work' from='dj@yak'>
<user name='DJ Adams' xmlns='jabber:iq:browse' jid='dj@yak'>
<ns><TT
CLASS="USERINPUT"
><B
>dj:public:favorites</B
></TT
></ns>
</user>
</iq></PRE
></P
><P
>and can be subsequently retrieved by anyone:</P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq type='get' to='dj@yak'>
<query xmlns='dj:public:favorites'/>
</iq>
RECV: <iq type='result' to='sabine@yak/Work' from='dj@yak'>
<query xmlns='<TT
CLASS="USERINPUT"
><B
>dj:public:favorites</B
></TT
>'>
<item url='http://dev.jabber.org'>Jabber DevZone</item>
<item url='http://www.scripting.com'>Scripting News</item>
</query>
</iq></PRE
></P
><P
>Publically stored data can contain multiple fragments qualified by
different namespaces, such as:</P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq type='set'>
<query xmlns='my:resume'>
<education xmlns='resume:education'>
<degree type='BA'>Classics</degree>
</education>
<employment xmlns='work:clients'>
<client from='2001'>Author, O'Reilly &amp; Associates, Inc.</client>
<client from='1999'>Deluxe Video Services</client>
<client from='1996'>Andersen Consulting</client>
...
</employment>
</query>
</iq></PRE
></P
><P
>However, the retrieval <I
CLASS="EMPHASIS"
>resolution</I
> is still limited to all of the
fragment defined by the top-level namespace (<TT
CLASS="LITERAL"
>my:resume</TT
>
in this case).</P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="JABTDG-CH-5A-SECT-2.11"
><TT
CLASS="LITERAL"
>jabber:iq:register</TT
></A
></H2
><P
>As the name suggests, the <TT
CLASS="LITERAL"
>jabber:iq:register</TT
> namespace
is used to conduct registration exchanges between the client and server. The
most obvious example of this is to create (<I
CLASS="EMPHASIS"
>register</I
>) a new user on the
Jabber server. <A
HREF="c6313.htm"
>Chapter 6</A
> covers user registration in
detail, so here we'll look at how to use the namespace to add or
change an entry in the JUD.</P
><P
>First we request the fields for registration with an IQ <TT
CLASS="LITERAL"
>get</TT
>:</P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq type='get' to='jud.yak' id='jud-2'>
<query xmlns='jabber:iq:register'/>
</iq>
RECV: <iq type='result' to='dj@yak/Work' from='jud.yak' id='jud-2'>
<query xmlns='jabber:iq:register'>
<instructions>
Complete the form to submit your searchable attributes
in the Jabber User Directory
</instructions>
<name/>
<first/>
<last/>
<nick/>
<email/>
</query>
</iq></PRE
></P
><P
>and then send an IQ <TT
CLASS="LITERAL"
>set</TT
> to set our information:</P
><P
><PRE
CLASS="SCREEN"
>SENT: <iq type='set' to='jud.yak' id='jud-3'>
<query xmlns='jabber:iq:register'>
<name>DJ Adams</name>
<first>DJ</first>
<last>Adams</last>
<nick>qmacro</nick>
<email>dj.adams@pobox.com</email>
</query>
</iq>
RECV: <iq type='result' to='dj@yak/Work' from='jud.yak'/></PRE
></P
><DIV
CLASS="NOTE"
><BLOCKQUOTE
CLASS="NOTE"
><P
><B
>Making requests for form fields: </B
>This idiom—making a request to a service to return the fields
appropriate for completion—is common in Jabber and is worth
bearing in mind if you're intending to build a Jabber client. The nature of the form field requests means that the client application
has to be flexible and accommodating, to bend itself around the
dynamic server.</P
></BLOCKQUOTE
></DIV
><P
>Services offering a registration mechanism are identifiable in the
list returned from a <TT
CLASS="LITERAL"
>jabber:iq:agents</TT
>
or a <TT
CLASS="LITERAL"
>jabber:iq:browse</TT
> query, as shown in
<A
HREF="x5334.htm#JABTDG-CH-5A-EX-8"
>Example 5a-3</A
>.</P
><DIV
CLASS="EXAMPLE"
><A
NAME="JABTDG-CH-5A-EX-8"
></A
><P
><B
>Example 5a-3. An <TT
CLASS="LITERAL"
>agents</TT
> or <TT
CLASS="LITERAL"
>browse</TT
> query reveals registration and search
mechanisms</B
></P
><P
><PRE
CLASS="SCREEN"
>RECV: <iq to='dj@yak/Work' type='result' from='yak'>
<query xmlns='jabber:iq:agents'>
<agent jid='jud.yak'>
<name>yak JUD (0.4)</name>
<service>jud</service>
<search/>
<register/>
</agent>
...
</query>
</iq>
...
RECV: <iq type='result' to='dj@yak/Work' from='yak'>
<service xmlns='jabber:iq:browse' type='jabber' jid='yak'
name='Jabber Server'>
<service type='jud' jid='jud.yak' name='yak JUD (0.4)'>
<ns>jabber:iq:search</ns>
<ns>jabber:iq:register</ns>
</service>
...
</service>
</iq></PRE
></P
></DIV
><P
>There are a couple of extra elements that are fairly common across different
implementations of the <TT
CLASS="LITERAL"
>jabber:iq:register</TT
> namespace:</P
><P
></P
><DIV
CLASS="VARIABLELIST"
><DL
><DT
><TT
CLASS="LITERAL"
><remove/></TT
></DT
><DD
><P
>When sent with an IQ set request, the <TT
CLASS="LITERAL"
><remove/></TT
>
tag requests that the registration be cancelled, revoked, or reversed.</P
></DD
><DT
><TT
CLASS="LITERAL"
><registered/></TT
></DT
><DD
><P
>When received in an IQ result, the <TT
CLASS="LITERAL"
><registered/></TT
>
tag signifies that registration has already been made with the service, and
any further registration IQ sets will serve to modify the current registration
details.</P
></DD
></DL
></DIV
><P
>Another example of registration using the <TT
CLASS="LITERAL"
>jabber:iq:register</TT
>
namespace is shown in <A
HREF="x9016.htm"
>the section called <I
>RSS punter</I
> in Chapter 8</A
>.</P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="JABTDG-CH-5A-SECT-2.12"
><TT
CLASS="LITERAL"
>jabber:iq:roster</TT
></A
></H2
><P
>In <A
HREF="x4089.htm#JABTDG-CH-5-SECT-5.4.2.3"
>the section called <I
>Presence Subscription</I
> in Chapter 5</A
>,
we looked at the presence subscription mechanism
used to coordinate and record information about the relationships
between users and how they exchange availability information. This mechanism
revolves around certain types of <TT
CLASS="LITERAL"
><presence/></TT
>
packets and storage of information in the users' <I
CLASS="EMPHASIS"
>rosters</I
>.</P
><P
>The roster structure is managed within the <TT
CLASS="LITERAL"
>jabber:iq:roster</TT
>
namespace. Clients make roster requests when they connect to the Jabber server,
to pull down the roster which is stored server side. They also update
the roster to add, change, or remove entries. However, roster updates aren't limited to just the client; there are certain attributes within each roster
item that are maintained by the server, in response to presence subscription
activity.</P
><P
>The rost
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -