📄 x5334.htm
字号:
from='jdev@conference.jabber.org'>
<query xmlns='jabber:iq:conference'>
<nick>qmacro</nick>
<name>Development Room</name>
<id>jdev@conference.jabber.org/650e81de0fcc265d43357ec09ded0ce421ecdff5</id>
</query>
</iq></PRE
></P
><P
>Closely linked with the <TT
CLASS="LITERAL"
>jabber:iq:conference</TT
> namespace
is the <TT
CLASS="LITERAL"
>jabber:iq:browse</TT
> namespace, which is also used
as a conduit for room-specific information and activity; see
<A
HREF="x5334.htm#JABTDG-CH-5A-SECT-2.5"
>the section called <I
><TT
CLASS="LITERAL"
>jabber:iq:browse</TT
></I
></A
>.</P
></DIV
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="JABTDG-CH-5A-SECT-2.7"
><TT
CLASS="LITERAL"
>jabber:iq:gateway</TT
></A
></H2
><P
>The <TT
CLASS="LITERAL"
>jabber:iq:gateway</TT
> namespace is used to envelope
a utility mechanism for converting external system identifiers (usernames,
and so on) to a JID equivalent. The requirement for this grew out of the
transport services to other IM systems (AIM, Yahoo!, and so on), which have
their own formats for user identification.</P
><P
>First, we know whether a service offers this utility from the namespace
list that is returned if we <I
CLASS="EMPHASIS"
>browse</I
> that service.
The next section shows how this might be done with the AIM Transport
service.</P
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="JABTDG-CH-5A-SECT-2.7.1"
>Discovering and using the AIM Transport's
<TT
CLASS="LITERAL"
>jabber:iq:gateway</TT
> utility</A
></H3
><P
>By browsing a service, we can tell whether it supports the
<TT
CLASS="LITERAL"
>jabber:iq:gateway</TT
> utility or not:</P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq type="get" id="aim1" to='aim.jabber.org'>
<query xmlns="jabber:iq:browse"/>
</iq>
RECV: <iq type='result' id='aim1' to='qmacro@jabber.org/winjab'
from='aim.jabber.org'>
<service xmlns='jabber:iq:browse' type='jabber'
jid='aim.jabber.org' name='AIM Transport'>
<ns>jabber:iq:register</ns>
<ns>jabber:iq:gateway</ns>
</service>
</iq></PRE
></P
><P
>We can now avail ourselves of this utility, to convert an AIM screenname
<I
CLASS="EMPHASIS"
>test ScreenName</I
> to the equivalent JID to be used
(in relation to the AIM transport service) in a Jabber context:</P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq type='get' to='aim.jabber.org' id='conv5'>
<query xmlns='jabber:iq:gateway'/>
</iq>
RECV: <iq type='result' to='qmacro@jabber.org/hailsham' id='conv5'
from='aim.jabber.org'>
<query xmlns='jabber:iq:gateway'>
<desc>Enter the user's screenname</desc>
<prompt/>
</query>
</iq></PRE
></P
><P
>We can reply, with an IQ set, with our screen name:</P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq type='set' to='aim.jabber.org' id='conf6'>
<query xmlns='jabber:iq:gateway'>
<prompt>test ScreenName</prompt>
</query>
</iq></PRE
></P
><P
>and receive the result of the transport-specific to JID conversion:</P
><P
><PRE
CLASS="SCREEN"
>RECV: <iq type='result' to='qmacro@jabber.org/Work' id='conf6'
from='aim.jabber.org'>
<query xmlns='jabber:iq:gateway'>
<prompt>testScreenName@aim.jabber.org</prompt>
</query>
</iq></PRE
></P
></DIV
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="JABTDG-CH-5A-SECT-2.8"
><TT
CLASS="LITERAL"
>jabber:iq:last</TT
></A
></H2
><P
>Like the <TT
CLASS="LITERAL"
>jabber:iq:time</TT
> and
<TT
CLASS="LITERAL"
>jabber:iq:version</TT
> namespaces, the
<TT
CLASS="LITERAL"
>jabber:iq:last</TT
> namespace allows a simple
query on uptime or idletime to be made on clients and servers alike.</P
><P
>Elapsed time information, in seconds, is returned in response to queries
in the <TT
CLASS="LITERAL"
>jabber:iq:last</TT
> namespace. If the query is made
of a server element (the Jabber server itself, or a component connected
to that server), then the information returned represents the time since
that element started, that is, the uptime:</P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq type='get' to='yak'>
<query xmlns='jabber:iq:last'></query>
</iq>
RECV: <iq type='result' to='dj@yak/Work' from='yak'>
<query xmlns='jabber:iq:last' seconds='2339811'/>
</iq></PRE
></P
><P
>Not all components support the <TT
CLASS="LITERAL"
>jabber:iq:last</TT
>
namespace; then again, in many cases the components—certainly those
that are connected with the <I
CLASS="EMPHASIS"
>library load</I
> mechanism
(see <A
HREF="c1223.htm"
>Chapter 4</A
>)—will have the same uptime
as the Jabber server they're connected to. In other cases, for
STDIO and TCP socket connected components that can be attached while
the Jabber server is running, the uptime may be less.
<A
NAME="JABTDG-CH-5-FOOTNOTE-1"
HREF="#FTN.JABTDG-CH-5-FOOTNOTE-1"
>[4]</A
></P
><P
>When a <I
CLASS="EMPHASIS"
>client</I
> disconnects, the last (un)availability
information in the
closing <TT
CLASS="LITERAL"
><presence/></TT
> element is stored for that user, along with the current time:</P
><P
><PRE
CLASS="SCREEN"
>SEND: <presence type='unavailable'>
<status>Gone home for the evening!</status>
</presence></PRE
></P
><P
>Making a <TT
CLASS="LITERAL"
>jabber:iq:last</TT
>
based query on a user's JID will return the information that was stored
from the <TT
CLASS="LITERAL"
><status/></TT
> tag as well as the number of
seconds representing the elapsed time since that disconnection (as a
difference between the time that the query was made and the time stored
for that user):</P
><P
></P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq type='get' to='dj@yak' id='lastq'>
<query xmlns='jabber:iq:last'/>
</iq>
RECV: <iq type='result' to='sabine@yak/Work' id='lastq' from='dj@yak'>
<query xmlns='jabber:iq:last' seconds='4521'>
Gone home for the evening!
</query>
</iq></PRE
></P
><P
>Notice that the JID of the user being queried
is <TT
CLASS="LITERAL"
>dj@yak</TT
> and not, for
example, <TT
CLASS="LITERAL"
>dj@yak/Work</TT
>. This, of course, is because the
user was still disconnected. The query was addressed to the user with no
resource specified, and was answered on behalf of the
user by the server (by the <TT
CLASS="LITERAL"
>mod_last</TT
> module—the same
module that looks after storing this information). In a disconnected
context, a resource is not appropriate for a user's JID (in the JSM);
they are only found in a connected context.</P
><P
>The <TT
CLASS="LITERAL"
>jabber:iq:last</TT
> is also designed to support a
similar client-targeted query, this time requesting information on
how long it has been since the user of that client was active (sent
a message, changed their presence, and so on). In contrast to the
previous <TT
CLASS="LITERAL"
>jabber:iq:last</TT
> query type, this query is
designed to be made to a connected user.</P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq type="get" to="dj@yak/Work">
<query xmlns='jabber:iq:last'/>
</iq>
RECV: <iq type='result' from='dj@yak/Work'>
<query xmlns='jabber:iq:last' seconds='19'/>
</iq></PRE
></P
><P
>Here we see that the user is using a client that supports this type
of <TT
CLASS="LITERAL"
>jabber:iq:last</TT
> query and was last active 19 seconds
ago.</P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="JABTDG-CH-5A-SECT-2.9"
><TT
CLASS="LITERAL"
>jabber:iq:oob</TT
></A
></H2
><P
>We've already seen a form of the <TT
CLASS="LITERAL"
>oob</TT
>—"Out Of
Band"
<A
NAME="AEN5758"
HREF="#FTN.AEN5758"
>[5]</A
>
—namespace in action, in the imaginary conversation in
<A
HREF="c324.htm"
>Chapter 1</A
>,
where <TT
CLASS="LITERAL"
>jabber:x:oob</TT
> was used to pass information
about a third-party file location (in the form of a Uniform Resource
Locator (URL).</P
><P
>The <TT
CLASS="LITERAL"
>jabber:iq:oob</TT
> namespace is used for pretty much
the same thing, except that its usage describes a very simple handshake
between two Jabber clients to exchange a file between themselves. (Yes, <I
CLASS="EMPHASIS"
>real</I
>
peer-to-peer for the purists.) Typically, the client sending the
file will only start listening for HTTP requests at the beginning
of the transfer process, and stop listening at the end of the transfer
process. The handshake is used to coordinate the process.</P
><P
>The sender initiates the process by making the file available via HTTP on
a specific (non-standard) port, and notifying the recipient of the URL:</P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq type='set' to='sabine@yak/winjab' id='file_2'>
<query xmlns='jabber:iq:oob'>
<url>http://192.168.0.7:5600/meetingnotes.txt</url>
<desc>Meeting Notes</desc>
</query>
</iq></PRE
></P
><P
>The recipient retrieves the file, and notifies the sender when the transfer
is complete.</P
><P
><PRE
CLASS="SCREEN"
>RECV: <iq type='result' to='dj@yak/Work' id='file_2' from='sabine@yak/winjab'/></PRE
></P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="JABTDG-CH-5A-SECT-2.10"
><TT
CLASS="LITERAL"
>jabber:iq:private</TT
></A
></H2
><P
>The <TT
CLASS="LITERAL"
>jabber:iq:private</TT
> namespace is traditionally
a way of storing user-defined data that should be kept private. Persistency across sessions
is achieved by storing the data in the user's records on the server.
The data is, of course, formatted in XML.</P
><DIV
CLASS="NOTE"
><BLOCKQUOTE
CLASS="NOTE"
><P
><B
>How private is private?: </B
>Private data stored by a user is only accessible to that user. Remember,
however, that the private data is stored on the server. Unencrypted. If
you're paranoid, encrypt it before storing it.</P
></BLOCKQUOTE
></DIV
><P
><A
HREF="x5334.htm#JABTDG-CH-5A-EX-6"
>Example 5a-1</A
> shows a typical use. The JIM client stores countless user preferences on a per-user
basis using this namespace. Once a user has connected and authenticated
with a Jabber server, those user preferences are retrieved and used by
the client to customize the settings.</P
><DIV
CLASS="EXAMPLE"
><A
NAME="JABTDG-CH-5A-EX-6"
></A
><P
><B
>Example 5a-1. JIM retrieves user preferences stored in a <TT
CLASS="LITERAL"
>jabber:iq:private</TT
> namespace</B
></P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq id="jabberim:prefs3860" type="get">
<query xmlns="jabber:iq:private">
<jabberIM xmlns="jabberim:prefs"/>
</query>
</iq>
RECV: <iq id='jabberim:prefs3860' type='result' from='dj@yak/Work'>
<query xmlns='jabber:iq:private'>
<jabberim xmlns='jabberim:prefs'
UseAutoAway='true'
AwayTime='5'
XATime='30'
AwayStatus='Away (auto)'
XAStatus='Ext. Away (auto)'
WizardShown='false'
... >
</jabberim>
</query>
</iq></PRE
></P
></DIV
><P
>In this example, you can see that a <TT
CLASS="LITERAL"
>private</TT
> namespace is used to qualify
the particular chunk of stored data, <TT
CLASS="LITERAL"
>jabberim:prefs</TT
>.
Also of interest is the difference between the tags—<TT
CLASS="LITERAL"
><jabberIM/></TT
> in the retrieval request
and <TT
CLASS="LITERAL"
><jabberim/></TT
> in the response. Again
we see evidence of an XML usage convention previously seen (for example,
in the Jabber server component configuration stanzas; see
<A
HREF="c1223.htm"
>Chapter 4</A
> for more details). The namespace itself
is critical, not the enclosing tag name. If the preferences were originally
stored using a tag name of <TT
CLASS="LITERAL"
><jabberim/></TT
>
then that's how it will be stored, and returned.</P
><P
>To add (or change) private data, use the namespace in an IQ set context:</P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq id="private-s3" type="set">
<query xmlns="jabber:iq:private">
<reminders xmlns="cal:events">
<event date='20010617'>Father's Day</event>
</reminders>
</query>
</iq></PRE
></P
><P
>Due to the way the <TT
CLASS="LITERAL"
>jabber:iq:private</TT
>
storage mechanism is currently implemented, you can only interact with <I
CLASS="EMPHASIS"
>one</I
>
private namespace-qualified chunk. In other words, a private store
request like this:</P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq id="private-s4" type="set">
<query xmlns="jabber:iq:private">
<reminders xmlns="cal:events">
<event date='20010617'>Father's Day</event>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -