On Tue, 24 Feb 2009 16:53:30 +0100 Jiří Zárevúcký <[email protected]> wrote:
> Hello all. > > I've been thinking about the current subscription management in the > XMPP-IM for some time now. I think it's not very well designed. It has some flaws. See my post about subscriptions, please. > For example, there's an obvious redundancy in the roster pushes and > subscription stanzas. For (almost) every subscription update / > request, there is a presence stanza and a roster push. But that only > applies to the contact, who receives the change. Also, the "ask" > attribute looks like a maimed boolean and roster pushes do not contain > all the state information - inbound request is missing. Hmmm. > Even though the client can track most of the changes by tracking > roster pushes and subscription stanzas, there is one change client can > never track. When there is an inbound subscription request with no > item and user declines it, other resources get no push and no presence > stanza - no notification. That is not really a big problem, but all > this inconsistency in pushes and presence stanzas makes it all seem > very chaotic and untidy. Well, yes. > Originally, I wanted to propose modifying roster pushes so they > contain all the state information (including eventual inbound > subscription request message), essentially leaving > subscription-managing presence stanzas only as the mean of requesting > the change, not presenting it to the other entity or the other > resources. Then one thing occured to me. Do we really need a separate > subscription handling for inbound and outbound presences? Users > generally don't want it separate. Users want mutual subscription. Is > there ever need to have one-side subscription? This would need a clean redesign. Not just a bunch of ideas. > Providing mechanism for just a mutual subscription, where there would > be only both-direction or pending or no subscription at all, would > immensely simplify things for both users and implementers. This would break things even further.... see my other post and consider what this change will do with the authority. Bidi-only association seems too simple to fit in the common needs IMO. > Yes, I > agree that immediate effect would be increasing complexity and need of > additional effort to maintain backward compatibility. That would be a > tricky task, but I believe that with proper interoperability rules, it > would be possible to make transition relatively painless. I believe > that in a long run, such change would be a huge improvement. You'd need to know if the transition gives or takes. > So, in case you are interested in this idea, I will continue with some > semantics I have on my mind. Otherwise, just tell me why do you think > it is not possible / feasible / wanted to implement it. I'm pretty > sure there is some hidden problem with this I don't realize. I suppose > many of you won't take me too seriously, since it would require too > massive change to the core protocol, but I'd appreciate if you thought > about it a bit. Thanks for any feedback. I believe it is impossible. But please provide your-words comparison.... and what it would bring. I might try to be the devil's advocate and add problems it would make :D. Pavel > > > > <item/> element would have the children defined in the current > XMPP-IM except: • there is no "ask" attribute > • the "subscription" attribute has following values > ∘ none - means there is no subscription sharing > ∘ pending-in - means the contact requests subscription sharing > ∘ pending-out - means the user requests subscription sharing > ∘ subscribed - means user is sharing presences with the contact > • there are three new optional child elements: > ∘ "request", whose character data is the message associated with > the subscription request > ∘ "ghost" (empty), which would work as a marker for items, that > are not yet in the roster (just holding information about the > request). > ∘ "remove" (empty) - same as the subscription="remove" in the > current specification; it's changed to a separate element because the > subscription attribute should only contain information about the > subscription, not a removal request > > As for the <presence/> stanza: > • "unsubscribed" and "subscribed" types are removed, since they are > no longer needed > > === Subscription request: > > Contact requesting the subscription would send the presence stanza as > usual: > > <presence type="subscribe" to="[email protected]"> > <status>Please subscribe me.</status> > </presence> > > The stanza would be delivered to the server and possibly forwarded to > the contact's server, but it would NOT be delivered to the contact > itself. Instead, contact would get an updated item. > > Scenario 1: contact is already in the roster > > <iq type="set" id="push1"> > <query xmlns="jabber:iq:roster"> > <item jid="[email protected]" > subscription="pending-in"> <request>Please subscribe me.</request> > <group>Friends</group> > </item> > </query> > </iq> > > Success case: > > <presence type="subscribe" to="[email protected]" /> > > When there is a pending request and user includes the "status" child, > it is ignored. > Server then updates subscription. > > <iq type="set" id="push2"> > <query xmlns="jabber:iq:roster"> > <item jid="[email protected]" > subscription="subscribed"> <group>Friends</group> > </item> > </query> > </iq> > > Failure case: > > <presence type="unsubscribe" to="[email protected]" /> > > Server responds: > > <iq type="set" id="push2"> > <query xmlns="jabber:iq:roster"> > <item jid="[email protected]" subscription="none"> > <group>Friends</group> > </item> > </query> > </iq> > > Scenario 2: contact in not in the roster > > Contact is added automatically to the roster with the "ghost" marker. > > <iq type="set" id="push1"> > <query xmlns="jabber:iq:roster"> > <item jid="[email protected]" > subscription="pending-in"> <request>Please subscribe me.</request> > <ghost /> > </item> > </query> > </iq> > > Success case: > > <presence type="subscribe" to="[email protected]" /> > > <iq type="set" id="push2"> > <query xmlns="jabber:iq:roster"> > <item jid="[email protected]" > subscription="subscribed" /> </query> > </iq> > > Failure case: > > <presence type="unsubscribe" to="[email protected]" /> > > <iq type="set" id="push2"> > <query xmlns="jabber:iq:roster"> > <item jid="[email protected]"> > <remove /> > </item> > </query> > </iq> > > Note that "ghost" item is promoted to a normal item upon success and > removed upon failure. If the contact is added via a roster set while > it is in "ghost" state, it is promoted and the subscription state is > preserved. Ghost item can't be removed by a removing roster set, > because it technically isn't in the roster. > > Scenario 3: contact withdraws it's sharing proposal > > <presence type="unsubscribe" to="[email protected]" /> > > The response is then exactly the same as if the user declined it. > Note: I think it is not necessary for client to know, who cancelled > the request. User knows, whether it was him or not. > Note2: Perhaps it would be wiser to disallow this, as it would open > the possibility of request spamming. Or perhaps just encourage > aggressive rate-limiting for requests. > > === Cancelling presence sharing > > Server: > <iq type="set" id="push1"> > <query xmlns="jabber:iq:roster"> > <item jid="[email protected]" > subscription="subscribed" /> </query> > </iq> > > User: > <presence type="unsubscribe" to="[email protected]" /> > > Server: > <iq type="set" id="push2"> > <query xmlns="jabber:iq:roster"> > <item jid="[email protected]" > subscription="none" /> </query> > </iq> > > === Outbound subscription request > > Server: > <iq type="set" id="push1"> > <query xmlns="jabber:iq:roster"> > <item jid="[email protected]" > subscription="none" /> </query> > </iq> > > User: > <presence type="subscribe" to="[email protected]"><status>My > request</status></presence> > > Server would change item, note how it contains it's own message: > <iq type="set" id="push2"> > <query xmlns="jabber:iq:roster"> > <item jid="[email protected]" > subscription="pending-out"> <request>My request</request> > </item> > </query> > </iq> > > If the contact wasn't in roster prior to the outbound request, it > would contain the "ghost" mark, which would work as described earlier. > > === Summary > > So, subscribe and unsubscribe presence stanzas are never sent from > server to client. They are only sent from client to server as a > request and from server to server as an update. All the updates for > clients are provided via roster pushes and the semantics are clear and > easy to understand. Subscription is defined for both directions at the > same time. What do you think? -- Freelance consultant and trainer in networking, communications and security. Web: http://www.pavlix.net/ Jabber, Mail: pavlix(at)pavlix.net OpenID: pavlix.net
