Thanks, this looks like a great start.
On Sun Nov 5 02:12:41 2006, Justin Karneges wrote:
> X. Stanza Acknowledgements
>
> X.1. Overview
>
> XMPP includes a method for acknowledging stanza
reception, to allow
> for
> transmission error detection and recovery.
>
> The following rules apply:
> 1. An initiating entity that complies with this
specification
> MUST include
> the 'version' attribute set to a value of
"1.0" in the initial
> stream
> header.
> 2. When a receiving entity that complies with this
specification
> receives
> an initial stream header that includes the
'version' attribute
> set to a
> value of at least "1.0", after sending a
stream header in reply
> (including the version flag), it MUST include an
<ack/> element
> (qualified by the 'urn:ietf:params ml:ns
mpp-a
ck' namespace)
> along
> with the list of other stream features it
supports.
>
> X.2. Narrative
>
> When an initiating entity activates the acknowledgement
feature
> with a
> receiving entity, the steps involved are as follows:
>
>
I'd be tempted to seperate out initial connection from
reconnection,
here.
> 1. The initiating entity opens a TCP connection and
initiates the
> stream
> by sending the opening XML stream header to the
receiving
> entity,
> including the 'version' attribute set to a value
of at least
> "1.0".
> 2. The receiving entity responds by opening a TCP
connection and
> sending
> an XML stream header to the initiating entity,
including the
> 'version'
> attribute set to a value of at least
"1.0".
> 3. The receiving entity offers the acknowledgement
feature to the
> initiating entity by including it with the list of
other
> supported
> stream features.
(Only after authentication)
> 4. The initiating entity issues the enable command
(i.e., a
> <enable/>
> element qualified by the 'urn:ietf:params ml:ns
mpp-a
ck'
> namespace)
> to instruct the receiving entity that it wishes to
enable the
> acknowledgement feature. The element MAY contain
a 'previd'
> attribute
> and a 'prevc' attribute, if the initiating entity
wishes to
> recover a
> previously known acknowledgement session. The
value of the
> 'previd'
> attribute is set to the same value as the 'id'
attribute of the
> <stream> in the previous session. The value
of the 'prevc'
> attribute,
> if applicable, is set to the last received
sequence number
> (discussed
> below) by the initiating entity. If the
initiating entity is
> not
> recovering a past session, the 'previd' and
'prevc' attributes
> MUST NOT
> be included.
(enable only gets sent after authentication)
> 5. The receiving entity MUST reply with an
<enabled/> element
> qualified by
> the 'urn:ietf:params ml:ns
mpp-a
ck' namespace. If the
> initiating
> entity provided a 'previd' attribute in the
<enable/> element,
> and the
> receiving entity supports session recovery, then
the receiving
> entity
> MAY provide a 'prevc' attribute in the
<enabled/> element.
> The value
> of this attribute is set to the last received
sequence number
> (discussed below) for the previous session. If
the receiving
> entity
> does not support session recovery, or does not
recognize the
> 'previd'
> as an earlier session, or there is no known last
received
> sequence
> number for the session, then the attribute MUST
NOT be
> included.
This looks good so far. You might want to note the receiving
entity
might discard old sessions after a fixed timeout in the
order of
minutes.
Bruce Fitzsimmons's comments make it clear that a sender
might want
to send unacked stanzas anyway, here, in order to reduce the
round-trip count, and have the receiver drop duplicates.
This is
quite reasonable on some links - it's a trade-off of
round-trips to
latency, however I think it only works when all stanzas have
a 'c'
attribute. (Although I freely admit to not having thought of
this
before, and not having thought it through).
Finally, the server might not realize the client's been
disconnected
before it reconnects. What needs to happen here is that the
server
essentially replays unacked stanzas and ditches the old
session, but
I've yet to remind myself what RFC3920 says about that.
> 6. When a stanza is sent by either the initiating or
receiving
> entity, an
> 'r' attribute ("request ack") or a 'c'
attribute ("sequence
> number")
> qualified by the 'urn:ietf:params ml:ns
mpp-a
ck' namespace
> MAY be
> provided in the top-level element of the stanza to
indicate how
> acknowledgements are to be handled with respect to
the stanza.
> If no
> acknowledgement processing is desired for a
stanza, then the
> attribute
> MUST NOT be included. Note that only stanzas
('message',
> 'presence',
> and 'iq', in the jabber:client or jabber:server
namespaces)
> can have
> this kind of processing applied. Non-stanza
elements, such as
> those
> related to authentication or other stream-level
purposes are
> not to be
> acknowledged using this protocol.
I would state that the value of "c" MUST be
strictly increasing (not
"monotonically increasing", that means
"strictly non-decreasing",
which'd be bad). I can't see any use-case for anything else.
Furthermore, I would state that any stanza with an
"r" attribute MUST
have a "c" attribute - see below for why.
> 7. When a stanza is received, containing an 'r'
attribute
> ("request ack")
> with a value of "true", the recipient
MUST acknowledge the
> stanza by
> sending an <a/> element qualified by the
> 'urn:ietf:params ml:ns
mpp-a
ck' namespace back to the sender.
> Stanzas not containing an 'r' attribute MUST NOT
be
> acknowledged.
> Several stanzas MAY be acknowledged at one time by
including
> an 'n'
> attribute in the <a/> element, set to the
integer value of the
> number
> of stanzas. An ack indicates stanza acceptance,
in that the
> stanza is
> now safe in the receiver's hands and that the
receiver will
> take care
> of it from that point. Acks do not indicate
successful
> delivery to a
> remote entity beyond the receiver. The sender
does not have
> to wait
> for an ack to continue sending stanzas. Acks
SHOULD be sent
> as soon as
> possible, and MUST NOT be withheld for any
condition other
> than a
> timeout. For example, a client with a slow
connection might
> want to
> collect many stanzas over a period of time before
acking, and
> a server
> might want to throttle incoming stanzas. As acks
indicate
> stanza
> acceptance, a server that is throttling stanzas
MUST defer the
> acks
> until the client is no longer being penalized.
Okay, here I diverge more... I would say that a receiver MAY
send an
ack even if not requested, if it is also sending other
stanzas. I'm
not wedded to this by any means, but it might be nice. The
intention
here is to allow a receiver to plonk an <a/> onto the
end of a packet
if it's sending. An alternate here would be to give several
possible
values for 'r', indicating whether you want an ack at all,
and if you
do, whether "sometime" or "immediate".
I'm not wedded to that either,
but I'd love to see some discussion.
Also, I would replace "Acks SHOULD be sent as soon as
possible [...]"
with something like:
Acks SHOULD be sent in a timely manner, however receivers
MAY delay
sending an ack for a short period in order to increase
efficiency.
Receivers MUST NOT delay sending an ack for more than 15
seconds,
allowing the requesting peer to timeout the connection after
30
seconds.
Rationale is that you want mandatory timeouts here, and I
too was a
little confused by what you meant there. Feel free to adjust
the
mandatory timeout figures. The idea is that a client gets to
be
assured that if it asks for an ack, if it hasn't had one for
30
seconds (in this case) the connection is dead.
Finally, I'd add in a mandatory prevc attribute in the
<a/> element,
to match the mandatory 'c' attribute in an 'r'-enabled
stanza. This
does mean that stanzas MUST be accepted in sequence, which I
don't
think is unreasonable. In turn, this renders the 'n'
attribute
obsolete.
Applycing to no particular section, some notes:
1) A 'c' or 'r' attribute only makes sense on the last
stanza in a
TCP packet. In general, any time you write any stanzas, you
may well
only care about 'c'/'r' attributes on the last one.
2) We need some mechanism for obtaining an ack when we've
nothing to
send. You could, of course, send an unrequested ack here,
with 'c'
and 'r' attributes.
3) But given (1) and (2), that implies that we could stick
all the
'c' and 'r' attributes onto only the <a/>, and append
an <a/> to
flushes to indicate synch points and request acks.
Point (3) is interesting, because it avoids servers having
to rewrite
stanzas (which was complained about, IIRC), *and* gives you
a free
hop-to-hop ping. So maybe that's worth discussing too.
Dave.
--
Dave Cridland - mailto:dave cridland.net - xmpp:dwd jabber.org
-
acap://acap.dave.cridland.net/byowner/user/dwd/bookmarks/
- http://dave.cridland.net/
a>
Infotrope Polymer - ACAP, IMAP, ESMTP, and Lemonade
|