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?
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:
Modify the library you use to accept more than one item in roster "set" request
Modify Tigase's code to push only 1 item in the "set" request
Switch to a different library which accepts more items in "set" request out of the box. Our, Tigase JaXMPP library handles this very well.
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">