powered by Jive Software

Improve Uploading Avatar Time

When reporting issues include

  • The used Smack version
    implementation "org.igniterealtime.smack:smack-android-extensions:4.3.0"
    implementation "org.igniterealtime.smack:smack-experimental:4.3.0"
    implementation "org.igniterealtime.smack:smack-tcp:4.3.0"
    implementation "org.minidns:minidns-android21:0.3.4"

XMPP Trace
The trace is very large to post here, so It is found here: https://pastebin.com/dQbSEpmJ

I,m using Smack to upload avatar. It takes long time and most of that time it times out (sometimes even 2min is not enough). Is there a way I can improve on that? Is there any other way to quickly upload avatar?

I know I can have just my own http service serving avatars, but I’m not willing to go that route right now. Fetching VCard avatar is very quick.

Here is the code I use:

fun setPhoto(path: String) = viewModelScope.launch(Dispatchers.IO) {
        try {
            val file = File(path)
            val vCardMgr = VCardManager.getInstanceFor(connection)
            val vCard = vCardMgr.loadVCard()
            vCard.setAvatar(Base64.encodeToString(file.readBytes(), Base64.DEFAULT), FileUtils.getMimeType(path))
            vCardMgr.saveVCard(vCard)
        } catch (e: Exception) {
            launch(Dispatchers.Main){
                Toast.makeText(chatApp.applicationContext, e.message, Toast.LENGTH_LONG).show()
            }
        }
    }

What am I doing wrong? Test is on local machine so I expected things to be very fast, but opposite is the case!

I’m not sure why uploading the avatar is slow for you. Maybe it is not Smack, but the server?
The recommended way to deal with user avatars is defined in XEP-0084: User Avatars. Sadly Smack does not have support for those (yet), however there is a pending PR that may add support for it soon.

Maybe you can get some inspiration from that :slight_smile:

1 Like

Hi Paull,
thanks for the comment. Have you ever tried out ths feature and see the response?
I also found it strange behavior, especially since am using local machine!
I will try with Openfire (currently using ejabberd) and see if there will be any difference.

I hope that PR gets accepted

I haven’t yet tried out setting avatars via VCard, however judging from the XEP, the client does not have to do any heavy lifting at all. It just has to send out one stanza and wait for the response, so I guess it is most likely a slow server component.

Another theory might be that you registered some synchronous listeners on the connection that block the reader thread and cause a deadlock in Smacks code which results in the timeout. Maybe check your server logs (with debug level 5 in ejabberd) to see how fast the server acknowledges the vcard stanza.

1 Like

Thanks for the hint, however I don’t understand the “you registered some synchronous listeners on the connection”. What do you mean by sync? How do I know the listerner is Sync or async? I have added chat listerner and am getting roster presence changes too

If you didnt do anything like connection.addSyncStanzaListener(...) you should be fine.

@flow could give you further tips to investigate the issue though.

No. I didn’t add that.

So I did further testing with Openfire and here is an error that actually occurs. I don’t know what it means exactly but my guess is the encoded text is too large to parse. I checked cropped file is 3MB. It is not a small size but I’m not sure why is it too large for XMPP.

Here is the log

2020.04.26 22:04:12 WARN  [socket_c2s-thread-3]: org.jivesoftware.openfire.nio.ConnectionHandler - Closing connection due to exception in session: (0x00000007: nio socket, server, /192.168.1.103:42064 => /192.168.1.101:5222)
org.apache.mina.filter.codec.ProtocolDecoderException: Stopped parsing never ending stanza (Hexdump: (redacted hex dump of never ending stanza))
	at org.jivesoftware.openfire.nio.XMLLightweightParser.read(XMLLightweightParser.java:192) ~[xmppserver-4.5.1.jar:4.5.1]
	at org.jivesoftware.openfire.nio.XMPPDecoder.doDecode(XMPPDecoder.java:38) ~[xmppserver-4.5.1.jar:4.5.1]
	at org.apache.mina.filter.codec.CumulativeProtocolDecoder.decode(CumulativeProtocolDecoder.java:180) ~[mina-core-2.1.3.jar:?]
	at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:254) [mina-core-2.1.3.jar:?]
	at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:650) [mina-core-2.1.3.jar:?]
	at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:49) [mina-core-2.1.3.jar:?]
	at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:1128) [mina-core-2.1.3.jar:?]
	at org.apache.mina.core.filterchain.IoFilterEvent.fire(IoFilterEvent.java:106) [mina-core-2.1.3.jar:?]
	at org.apache.mina.core.session.IoEvent.run(IoEvent.java:89) [mina-core-2.1.3.jar:?]
	at org.apache.mina.filter.executor.OrderedThreadPoolExecutor$Worker.runTask(OrderedThreadPoolExecutor.java:766) [mina-core-2.1.3.jar:?]
	at org.apache.mina.filter.executor.OrderedThreadPoolExecutor$Worker.runTasks(OrderedThreadPoolExecutor.java:758) [mina-core-2.1.3.jar:?]
	at org.apache.mina.filter.executor.OrderedThreadPoolExecutor$Worker.run(OrderedThreadPoolExecutor.java:697) [mina-core-2.1.3.jar:?]
	at java.lang.Thread.run(Thread.java:832) [?:?]

Openfire has a (configurable) maximum stanza size limit. I think it’s on 2MB. Note that when you base64 encode binary data, the encoded result will be a lot larger than the unencoded original. I suggest that you reduce the image size in your vcard, or use another mechanism to exchange the data.

2 Likes

Thank you for the confirmation. I think reducing Image size is the way to go!
Using other means is viable and will look unto it!

Again Thank you!

SO post

1 Like