📄 x624.htm
字号:
<HTML
><HEAD
><TITLE
>Request/Response</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.64
"><LINK
REL="HOME"
TITLE="Programming Jabber"
HREF="book1.htm"><LINK
REL="UP"
TITLE="Inside Jabber"
HREF="c445.htm"><LINK
REL="PREVIOUS"
TITLE="Payload Carrier"
HREF="x557.htm"><LINK
REL="NEXT"
TITLE="Component/Service Architecture"
HREF="x712.htm"></HEAD
><BODY
CLASS="SECT1"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming Jabber</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x557.htm"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Chapter 2. Inside Jabber</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x712.htm"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="JABTDG-CH-2-SECT-2.5"
>Request/Response</A
></H1
><P
>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. <A
HREF="x624.htm#JABTDG-CH-2-EX-4"
>Example 2-4</A
>
shows a typical HTTP request/response pairing.</P
><DIV
CLASS="EXAMPLE"
><A
NAME="JABTDG-CH-2-EX-4"
></A
><P
><B
>Example 2-4. A typical HTTP request/reponse</B
></P
><P
><PRE
CLASS="SCREEN"
>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>
...</PRE
></P
></DIV
><P
>It shows us the request verb <TT
CLASS="LITERAL"
>GET</TT
>, and the specification
of what to retrieve (the <TT
CLASS="LITERAL"
>/home.html</TT
> document), and it
shows us what is returned in response. </P
><P
>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
<I
CLASS="EMPHASIS"
>immediately</I
> 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
<I
CLASS="EMPHASIS"
>Info/Query</I
>, or IQ for
short; the Jabber element employed in the implementation of this
model is <TT
CLASS="LITERAL"
><iq/></TT
>.</P
><P
>This IQ model has many uses in providing Jabber's basic IM features.
<A
HREF="x624.htm#JABTDG-CH-2-FIG-1"
>Figure 2-1</A
> shows the element traffic in a
typical IQ-based conversation.</P
><DIV
CLASS="FIGURE"
><A
NAME="JABTDG-CH-2-FIG-1"
></A
><P
><B
>Figure 2-1. Element traffic in an IQ-based conversation</B
></P
><PRE
CLASS="SCREEN"
> +----------+ +----------+
| entity 1 | IQ-get ---> | entity 2 |
| | | |
| | <--- IQ-res | |
| | | |
| | | |
| | | |
| | IQ-set ---> | |
| | | |
| | <--- IQ-res | |
| | | |
+----------+ +----------+ </PRE
></DIV
><P
><A
HREF="x624.htm#JABTDG-CH-2-EX-5"
>Example 2-5</A
>,
<A
HREF="x624.htm#JABTDG-CH-2-EX-6"
>Example 2-6</A
> and
<A
HREF="x624.htm#JABTDG-CH-2-EX-7"
>Example 2-7</A
>
show typical uses of the
<TT
CLASS="LITERAL"
><iq/></TT
> element to effect the IQ request/response
model.</P
><DIV
CLASS="EXAMPLE"
><A
NAME="JABTDG-CH-2-EX-5"
></A
><P
><B
>Example 2-5. A simple client version query via the IQ model</B
></P
><P
><PRE
CLASS="SCREEN"
>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></PRE
></P
></DIV
><P
>In <A
HREF="x624.htm#JABTDG-CH-2-EX-5"
>Example 2-5</A
>
we see that the equivalent of HTTP's <TT
CLASS="LITERAL"
>GET</TT
> verb
is the <TT
CLASS="LITERAL"
>type='get'</TT
> attribute of the
<TT
CLASS="LITERAL"
><iq/></TT
> element, and that the equivalent of
<I
CLASS="EMPHASIS"
>what</I
> to get (<TT
CLASS="LITERAL"
>/home.html</TT
>) is our
namespace specification in the <TT
CLASS="LITERAL"
><query/></TT
>
tag. </P
><P
><A
HREF="x624.htm#JABTDG-CH-2-EX-6"
>Example 2-6</A
>
shows a two-stage request/response model. First, a query is made,
using the <TT
CLASS="LITERAL"
><iq/></TT
> 'get' type with an
id of 'reg1', to discover
which fields are required for user registration. Then, the actual
user registration attempt is made with the <TT
CLASS="LITERAL"
><iq/></TT
>
'set' (id 'reg2'). In this second stage, we can see a link with HTTP's
<TT
CLASS="LITERAL"
>POST</TT
> verb - whereby data is sent along with the request.
<A
NAME="JABTDG-CH-2-FOOTNOTE-3"
HREF="#FTN.JABTDG-CH-2-FOOTNOTE-3"
>[1]</A
> </P
><DIV
CLASS="EXAMPLE"
><A
NAME="JABTDG-CH-2-EX-6"
></A
><P
><B
>Example 2-6. A multiple-phase IQ to register a user</B
></P
><P
><PRE
CLASS="SCREEN"
>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'/></PRE
></P
></DIV
><P
>While HTTP is primarily a client-server protocol (although these
words have less and less meaning in a P2P (peer-to-peer) environment where
each participating entity can be both client and server),
<A
HREF="x624.htm#JABTDG-CH-2-EX-5"
>Example 2-5</A
>
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.</P
><P
><A
HREF="x624.htm#JABTDG-CH-2-EX-7"
>Example 2-7</A
> shows how an IQ-based conversation
can extend beyond the <I
CLASS="EMPHASIS"
>get ... result</I
> or
<I
CLASS="EMPHASIS"
>set ... result</I
> model. It shows how the IQ model
can be used to deliver results of a search request in stages.</P
><DIV
CLASS="EXAMPLE"
><A
NAME="JABTDG-CH-2-EX-7"
></A
><P
><B
>Example 2-7. Staggered response from IQ-based search request</B
></P
><P
>The search request:</P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq type='set' to='ldap.company-a.com' id='801'>
<query xmlns='jabber:iq:search'>
<group>Support</group>
</query>
</iq></PRE
></P
><P
>The first part of the response—the first record found:</P
><P
><PRE
CLASS="SCREEN"
>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></PRE
></P
><P
>The second record found:</P
><P
><PRE
CLASS="SCREEN"
>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></PRE
></P
><P
>The last record found:</P
><P
><PRE
CLASS="SCREEN"
>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></PRE
></P
><P
>No more records have been found and no more results are sent; instead,
an "end marker", signified by the <TT
CLASS="LITERAL"
>type='result'</TT
> attribute,
is sent.</P
><P
><PRE
CLASS="SCREEN"
>RECV: <iq type='result' from='ldap.company-a.com'
to='jim@company-a.com/home' id='801'>
<query xmlns='jabber:iq:search'/>
</iq></PRE
></P
></DIV
><P
>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:</P
><P
><PRE
CLASS="SCREEN"
>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/></PRE
></P
><P
>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:</P
><P
><PRE
CLASS="SCREEN"
>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></PRE
></P
><P
>and then this:</P
><P
><PRE
CLASS="SCREEN"
>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+1200</tz>
<display>Tue Jun 12 06:59:14 2001</display>
</query>
</iq></PRE
></P
><P
>That's the reason for the <TT
CLASS="LITERAL"
>id</TT
> attribute in the examples
earlier in this section. Between a request and a response, any
<TT
CLASS="LITERAL"
>id</TT
> attribute value in the
<TT
CLASS="LITERAL"
><iq/></TT
> element is preserved, allowing the
requester to match up <TT
CLASS="LITERAL"
><iq/></TT
> request / response
pairs. Using the <TT
CLASS="LITERAL"
>id</TT
> attribute, we can piece together
related fragments of individual conversations, which in this case were
a pair of client time queries.</P
></DIV
><H3
CLASS="FOOTNOTES"
>Notes</H3
><TABLE
BORDER="0"
CLASS="FOOTNOTES"
WIDTH="100%"
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.JABTDG-CH-2-FOOTNOTE-3"
HREF="x624.htm#JABTDG-CH-2-FOOTNOTE-3"
>[1]</A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
>Okay, data can also be sent with an HTTP <TT
CLASS="LITERAL"
>GET</TT
> request, but
let's just not go there, for the sake of the comparison. ;-)</P
></TD
></TR
></TABLE
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x557.htm"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.htm"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x712.htm"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Payload Carrier</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c445.htm"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Component/Service Architecture</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -