⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 x7499.htm

📁 Its a xmpp protocol book
💻 HTM
📖 第 1 页 / 共 4 页
字号:
>ask</TT
>
attribute as there's no current request going from <I
CLASS="EMPHASIS"
>dj</I
>
to the script.</P
><P
>While <I
CLASS="EMPHASIS"
>dj</I
>'s roster item for the script shows a
<TT
CLASS="LITERAL"
>subscription</TT
> value of "to", the
<I
CLASS="EMPHASIS"
>script</I
>'s roster item for <I
CLASS="EMPHASIS"
>dj</I
>
shows a <TT
CLASS="LITERAL"
>subscription</TT
> value of "from":</P
><P
><PRE
CLASS="SCREEN"
>&#60;item jid='dj@gnu.pipetree.com' subscription='from' ask='subscribe'/&#62;</PRE
></P
><P
>which shows that the script
has a subscription <I
CLASS="EMPHASIS"
>from</I
> <I
CLASS="EMPHASIS"
>dj</I
>.</P
><P
>Furthermore, remember that the script not only accepts
<I
CLASS="EMPHASIS"
>dj</I
>'s subscription request, but sends a reciprocal
one of its own. (Hence the <TT
CLASS="LITERAL"
>ask='subscribe'</TT
> status in
the item.) When <I
CLASS="EMPHASIS"
>dj</I
> accepts this request,
the roster item changes yet again to reflect the balanced relationship:</P
><P
><PRE
CLASS="SCREEN"
>&#60;item jid='cvsmsg@gnu.pipetree.com' subscription='both'/&#62;</PRE
></P
></DD
></DL
></DIV
><P
><I
CLASS="EMPHASIS"
>Request to unsubscribe</I
></P
><P
>We want the script to handle requests to <I
CLASS="EMPHASIS"
>unsubscribe</I
>
from its presence in the same way:</P
><P
><PRE
CLASS="SCREEN"
>    # unsubscription request: 
    # - accept their unsubscription
    # - send request for unsubscription to their presence
    elif type == 'unsubscribe':
        print "unsubscribe request from %s" % (who)
        con.send(Jabber.Presence(to=who, type='unsubscribed'))
        con.send(Jabber.Presence(to=who, type='unsubscribe'))&#13;</PRE
></P
><P
>The only difference between this section and the previous one is that it
deals with requests to <I
CLASS="EMPHASIS"
>unsubscribe</I
> as opposed to 
<I
CLASS="EMPHASIS"
>subscribe</I
> to presence. Otherwise it works in exactly
the same way. A sequence of <TT
CLASS="LITERAL"
>&#60;presence/&#62;</TT
>
elements used in an "unsubscription conversation" between 
<I
CLASS="EMPHASIS"
>dj</I
> and the script, and the changes to the
roster <TT
CLASS="LITERAL"
>&#60;item/&#62;</TT
> tags on each side,
is shown in <A
HREF="x7499.htm#JABTDG-CH-7-FIG-6"
>Figure 7-6</A
>.</P
><DIV
CLASS="FIGURE"
><A
NAME="JABTDG-CH-7-FIG-6"
></A
><P
><B
>Figure 7-6. <TT
CLASS="LITERAL"
>&#60;presence/&#62;</TT
> elements and
roster <TT
CLASS="LITERAL"
>&#60;item/&#62;</TT
>s in an
"unsubscription conversation"</B
></P
><PRE
CLASS="SCREEN"
>&#13;NOTE: This diagram needs some design explanation and help!

+------------------------------------------------------------------------------------------+
| Elements from dj                                                  Elements from cvsmsg   |
|         +-------------------------------------------------------------+                  |
|         | dj's roster items                cvsmsg's roster items      |                  |
|         +-------------------------------------------------------------+                  |
|         |                                                             |                  |
|         | &#60;item                           &#60;item                       |                  |
|         |  jid='cvsmsg@gnu.pipetree.com'   jid='dj@gnu.pipetree.com'  |                  |
|         |  subscription='both'/&#62;           subscription='both'/&#62;      |                  |
|                                                                       |                  |
|&#60;presence                                                              |                  |
| type='unsubscribe'                                                    |                  |
| to='cvsmsg@gnu.pipetree.com'/&#62;                                        |                  |
|                                                                       |                  |
|         | &#60;item                           &#60;item                       |                  |
|         |  jid='cvsmsg@gnu.pipetree.com'   jid='dj@gnu.pipetree.com'  |                  |
|         |  subscription='both'             subscription='both'/&#62;      |                  |
|         |  ask='unsubscribe'/&#62;                                        |                  |
|         |                                                                                |
|         |                                                     &#60;presence                  |
|         |                                                      type='unsubscribed'       |
|         |                                                      to='dj@gnu.pipetree.com'/&#62;|
|         |                                                                                |
|         | &#60;item                           &#60;item                       |                  |
|         |  jid='cvsmsg@gnu.pipetree.com'   jid='dj@gnu.pipetree.com'  |                  |
|         |  subscription='from'/&#62;           subscription='to'/&#62;        |                  |
|         |                                                                                |
|         |                                                     &#60;presence                  |
|         |                                                      type='unsubscribe'        |
|         |                                                      to='dj@gnu.pipetree.com'/&#62;|
|         |                                                                                |
|         | &#60;item                           &#60;item                       |                  |
|         |  jid='cvsmsg@gnu.pipetree.com'   jid='dj@gnu.pipetree.com'  |                  |
|         |  subscription='from'/&#62;           subscription='to'          |                  |
|         |                                  ask='unsubscribe'/&#62;        |                  |
|                                                                       |                  |
|&#60;presence                                                              |                  |
| type='unsubscribed'                                                   |                  |
| to='cvsmsg@gnu.pipetree.com'/&#62;                                        |                  |
|                                                                       |                  |
|         | &#60;item                           &#60;item                       |                  |
|         |  jid='cvsmsg@gnu.pipetree.com'   jid='dj@gnu.pipetree.com'  |                  |
|         |  subscription='none'/&#62;           subscription='none'/&#62;      |                  |
|         |                                                             |                  |
|         +-------------------------------------------------------------+                  |
|                                                                                          |
+------------------------------------------------------------------------------------------+</PRE
></DIV
><P
><I
CLASS="EMPHASIS"
>Accepted subscription or unsubscription</I
></P
><P
>While we must take action on presence types <I
CLASS="EMPHASIS"
>subscribe</I
>
and <I
CLASS="EMPHASIS"
>unsubscribe</I
> we don't really need to do anything
for their
<I
CLASS="EMPHASIS"
>acknowledgement</I
> counterparts. We can see these 
counterparts - <I
CLASS="EMPHASIS"
>subscribed</I
> and
<I
CLASS="EMPHASIS"
>unsubscribed</I
> ("I have accepted your request and 
you are now (un)subscribed to my presence.")</P
><P
>Just for illustration purposes, we'll include a couple of conditions
to let us know what's going on when the script runs:</P
><P
><PRE
CLASS="SCREEN"
>    elif type == 'subscribed':
        print "we are now subscribed to %s" % (who)

    elif type == 'unsubscribed':
        print "we are now unsubscribed to %s" % (who)&#13;</PRE
></P
></DIV
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="JABTDG-CH-7-SECT-3.2.4"
>Availability information</A
></H3
><P
>Apart from the types of <TT
CLASS="LITERAL"
>&#60;presence/&#62;</TT
>
element 
covering the presence subscription process, we should also expect
the basic availability elements:</P
><P
><PRE
CLASS="SCREEN"
>&#60;presence&#62;...&#60;/presence&#62;</PRE
></P
><P
>and</P
><P
><PRE
CLASS="SCREEN"
>&#60;presence type='unavailable'/&#62;</PRE
></P
><P
><I
CLASS="EMPHASIS"
>Availability</I
></P
><P
>It is an available <TT
CLASS="LITERAL"
>&#60;presence/&#62;</TT
>
element on which the functionality of the script hinges.</P
><P
><PRE
CLASS="SCREEN"
>    elif type == 'available':
        print "%s is available (%s/%s)" % (who, prs.getShow(), prs.getStatus())
        if prs.getShow() != 'dnd' and who == cvsuser:
            con.send(Jabber.Message(cvsuser, message, subject="CVS Watch Alarm"))&#13;</PRE
></P
><P
>This <TT
CLASS="FUNCTION"
>presenceCB()</TT
> subroutine is set up to handle
<TT
CLASS="LITERAL"
>&#60;presence/&#62;</TT
> elements. In a typical 
execution scenario, where the script is subscribed to the presence of
many potential CVS notification recipients, the subroutine is going to
be called to handle the availability information of all those 
recipients that happen to be connected to Jabber at the moment of 
notification. We're only interested in the availability information
of one particular recipient (<TT
CLASS="LITERAL"
>who == cvsuser</TT
>)
as well as checking on the contents of the 
<TT
CLASS="LITERAL"
>&#60;show/&#62;</TT
> tag.</P
><P
>If we get a match, we can send the notification message by creating
a <TT
CLASS="LITERAL"
>Jabber.Message</TT
> node that will look like this:</P
><P
><PRE
CLASS="SCREEN"
>&#60;message to='dj@gnu.pipetree.com'&#62;
  &#60;subject&#62;CVS Watch Alarm&#60;/subject&#62;
  &#60;body&#62;
    testproject file4
    ---
    Triggered edit watch on /usr/local/cvsroot/testproject
    By piers
  &#60;/body&#62;
&#60;/message&#62;</PRE
></P
><P
>As before, once created, the node can be sent with the 
<TT
CLASS="LITERAL"
>con.send()</TT
> method call.</P
><P
><I
CLASS="EMPHASIS"
>Unavailability</I
></P
><P
>Like the conditions for the presence subscription and unsubscription 
acknowledgements, we're including a final condition to deal with the
case where a recipient disconnects from the Jabber server during the
execution of our script: an <I
CLASS="EMPHASIS"
>unavailable</I
> 
<TT
CLASS="LITERAL"
>&#60;presence/&#62;</TT
> element will be sent:</P
><P
><PRE
CLASS="SCREEN"
>    elif type == 'unavailable':
        print "%s is unavailable" % (who)&#13;</PRE
></P
><P
>We're simply logging such an event for illustration purposes.</P
></DIV
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="JABTDG-CH-7-SECT-3.2.5"
>Connection and authentication</A
></H3
><P
>Most of the main part of the script is the same as the non-sensitive
version from <A
HREF="x6950.htm"
>the section called <I
>CVS notification</I
></A
>; reading in the 
notification message, preparing a connection to the Jabber server,
and trying to connect.</P
><P
><PRE
CLASS="SCREEN"
>for line in sys.stdin.readlines(): message = message + line

con = Jabber.Connection(host=Server)

try:
    con.connect()
except XMLStream.error, e:
    print "Couldn't connect: %s" % e 
    sys.exit(0)

con.auth(Username,Password,Resource)&#13;</PRE
></P
></DIV
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="JABTDG-CH-7-SECT-3.2.6"
>Registration of <TT
CLASS="LITERAL"
>&#60;presence/&#62;</TT
> handler</A
></H3
><P
>While we've <I
CLASS="EMPHASIS"
>defined</I
> our <TT
CLASS="FUNCTION"
>presenceCB()</TT
>
subroutine to handle
<TT
CLASS="LITERAL"
>&#60;presence/&#62;</TT
> packets, we haven't actually told
the Jabber library about it. The call to the
<TT
CLASS="FUNCTION"
>setPresenceHandler()</TT
> method of the connection object
does this for us, performing the "Register handler" step shown in 
<A
HREF="x7499.htm#JABTDG-CH-7-FIG-5"
>Figure 7-5</A
>:</P
><P
><PRE
CLASS="SCREEN"
>con.setPresenceHandler(presenceCB)&#13;</PRE
></P
></DIV
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="JABTDG-CH-7-SECT-3.2.7"
>Request for roster</A
></H3
><P
>It's easy to guess what the next method call does:</P
><P
><PRE
CLASS="SCREEN"
>con.requestRoster()</PRE
></P
><P
>It makes a request for the roster by sending an IQ-get with a 
query qualified by the <TT
CLASS="LITERAL"
>jabber:iq:roster</TT
> namespace:</P
><P
><PRE
CLASS="SCREEN"
>&#60;iq type='get' id='3'&#62;
  &#60;query xmlns='jabber:iq:roster'/&#62;
&#60;/iq&#62;</PRE
></P
><P
>to which the server responds with an IQ-result:</P
><P
><PRE
CLASS="SCREEN"
>&#60;iq type='result' id='3'&#62;
  &#60;query xmlns='jabber:iq:roster'&#62;
    &#60;item jid='dj@gnu.pipetree.com' subscription='both'/&#62;
    &#60;item jid='piers@jabber.org' subscription='both'/&#62;
    &#60;item jid='shiels@jabber.org' subscription='both'/&#62;
    ...
  &#60;/query&#62;
&#60;/iq&#62;</PRE
></P
><P
>However, as there are no explicit references to the roster anywhere
in the script, it's not as easy to guess why we request the roster
in the first place. We know that our client-side copy is merely a "slave" copy,
and even more relevant here, we know that <I
CLASS="EMPHASIS"
>subscription</I
>
information in the roster <TT
CLASS="LITERAL"
>&#60;item/&#62;</TT
> tags
is managed by the server&mdash;we as a client don't
need to (in fact, <I
CLASS="EMPHASIS"
>shouldn't</I
>) do anything to maintain 
the <TT
CLASS="LITERAL"
>subscription</TT
> and <TT
CLASS="LITERAL"
>ask</TT
>
attributes and keep them up to date.</P
><P
>So why do we request it?</P
><P
>Basically, it's because there's a fundamental difference between
<TT
CLASS="LITERAL"
>&#60;presence/&#62;</TT
> elements used to convey
availability information, and <TT
CLASS="LITERAL"
>&#60;presence/&#62;</TT
>
elements used to convey presence subscription information. If John
sends Jim availability information in a
<TT
CLASS="LITERAL"
>&#60;presence/&#62;</TT
> element, whether directly
(with a <TT
CLASS="LITERAL"
>to</TT
> attribute) or indirectly (through
the distribution of that element by the server to Jim as a subscriber
to John's presence), and Jim's offline, on holiday, it doesn't make much
sense to store and forward it to him when he next connects:</P
><P
>[<I
CLASS="EMPHASIS"
>Jim connects to Jabber after being away for two weeks</I
>]</P
><P
>Jabber server: "<I
CLASS="EMPHASIS"
>Here's some availability information for John, dated 9 days ago."</I
></P
><P
>Jim: "<I
CLASS="EMPHASIS"
>Who cares?</I
>"</P
><P
><TT
CLASS="LITERAL"
>&#60;presence/&#62;</TT
> elements conveying availability
information are <I
CLASS="EMPHASIS"
>not</I
> stored and forwarded if they
can't be delivered because the intended recipient is offline. What would
be the point?</P
><P
>However, <TT
CLASS="LITERAL"
>&#60;presence/&#62;</TT
> elements that convey
subscription information are a different kettle of fish. While it's not
important that I'm punted out of date availability information when I 
next connect to my Jabber client, any subscription (or unsubscription)
requests or confirmations that were sent to me <I
CLASS="EMPHASIS"
>are</I
>
important. So they need to be stored and forwarded.</P
><P
>As we've already seen, the presence subscription mechanism and rosters

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -