Projects tigase _server server-core Issues #421
Roster responses are of a type="set" but include multiple "item" elements (#421)
Jaume Paternoy opened 10 years ago

Hi all.

I'm customizing my server roster with an integration with another system. This integration is basically a custom implementation of DynamicRosterIfc and has worked fine for a long time.

Now, i am developing an Android XMPP client with Smack and roster was not loading. After some research, I realized that the library is expecting only one "item" inside multiple "set" responses, or a single response of type "result". But Tigase is generating a response of type "set" with several items inside, and as I read in the XMPP specification, this is not correct.

Do you think, as I do, that this is a bug with DynamicRosters? Am I possibly doing something wrong?

Those are some example messages:

My request:

<iq id="xTtpS-5"type="get">

First response:

<iq id="xTtpS-5"to="user2@sandbox.com/Smack"type="result"xmlns="jabber:client">

Second response:

<iq id="tig5"to="user2@sandbox.com/Smack"type="set"xmlns="jabber:client">

  <item jid="user3@sandbox.com"name="User 3"subscription="both"/>

  <item jid="user4@sandbox.com"name="User 4"subscription="both"/>

  <item jid="user5@sandbox.com"name="User 5"subscription="both"/>

  <item jid="user6@sandbox.com"name="User 6"subscription="both"/>
Artur Hefczyc commented 10 years ago

This is not a bug but intentional behavior. Could you please point me to the specification part which says this is incorrect? It was implemented long time ago based on the specification available at that time.

The motivation behind this implementation is that, the Tigase responds with "result" response to roster "get" for all roster items in the standard user's roster and then sends a number of "set" stanzas with roster items from dynamic roster implementation.

The reason why this is many "set" requests is that many deployments which used dynamic roster had a very large contact lists generated by a dynamic roster. Sending a single stanza with 1,000 items for example would break any web based XMPP client (JavaScript client) as the resources consumed by JavaScript would exceed what is allowed by most web browsers. It consumed a lot of memory and CPU and time to parse and process such a large XML data. So, the solution was to split 1 large "result" stanza into multiple "set" elements. And now, again, sending 1,000 roster items, each on a separate "set" request, would require 1,000 XMPP packets, which is a lot of traffic and takes very long time for the user's roster to show. So the optimization was to put multiple roster items into a single "set" request. From what I remember it was not disallowed at the time of implementation and worked quite well.

Jaume Paternoy commented 10 years ago

Hi Artur. Thanks for your quick response.

I understand the performance reasons you expose. It has really worked well with lots of different clients I have tried, but our Android implementation showed up this issue. I made a bit of research on this topic, because as I saw in Smack client library, these iq messages with multiple items are being explicitly refused with a dedicated if block. Finally, I found the XMPP specification refering on this topic, [[http://xmpp.org/rfcs/rfc6121.html#roster-syntax-actions-push]]. There you can see the following:

The element in a roster push MUST contain one and only one element.

What do you think? Any suggestions?

Artur Hefczyc commented 10 years ago

Thank you for the link to the spec. The spec indeed says that only one element is allowed. I also remember discussions on the XMPP mailing lists about this and many members suggested that more elements should be allowed. This is probably the reason why most of clients accept more than 1 element in the "set" request.

The specification allows for sending only one element because it discusses a different use case. This section is about changing an item (adding, removing, updating). In this scenario it makes sense to allow for only one item in the request. However, in case of out use-case where we push entire roster, putting a single item in a request would be highly inefficient.

So I can see a few options for you:

  1. Modify the library you use to accept more than one item in roster "set" request

  2. Modify Tigase's code to push only 1 item in the "set" request

  3. Switch to a different library which accepts more items in "set" request out of the box. Our, Tigase JaXMPP library handles this very well.

issue 1 of 1
Type
Bug
Priority
Normal
Assignee
RedmineID
2641
Issue Votes (0)
Watchers (0)
Reference
tigase/_server/server-core#421
Please wait...
Page is in error, reload to recover