Take two Smack XMPP Chat clients, let them send files to each other using the IBB protocol (XEP-0047: In-Band Bytestreams (IBB))
First time file transfer is successful
Restart XMPP server (Openfire)
Wait until Clients reconnect
Resend file
Transfer is not successful.
A empty file is generated at the receiving site.
Errors in the messages are:
<error type='modify'><not-acceptable> in response on a <open xmlns="http://jabber.org/protocol/ibb">
<error type='cancel'><item-not-found> in response on a <data xmlns="http://jabber.org/protocol/ibb" >' or '<close xmlns="http://jabber.org/protocol/ibb" >
Empty file is caused by the client not capable of handling the errors correctly. The xmpp errors however are caused by a duplicate InBandBytestreamManager which is initiated on the reconnect. The IBBTransferNegotiator however has still a reference to the original InBandBytestreamManager.
Could you alborate on that? What makes the client incapable of handling the errors correctly.
That sounds wrong. All Manager instances should be a singleton with respect to exactly one connection instance. You statement sounds like there could be more than one InBandBytestreamManger per connection, which also potentially is the underlying probelm? If so, then
just helps with the symptoms, but does not fix the actual issue. Or am I mistaken?
The error is there are more than one InBandBytestreamManger's per connection. Due to the restart of the server a connectionClosedOnError is triggered. This triggers the disableService of the InBandBytestreamManger which closes and clears the current instance of the InBandBytestreamManger, although the connection is not closed yet. The IBBTransferNegotiator has through the FileTransferNegotiator manager its own connection-singleton instance which is not cleared/cleaned by the connectionClosedOnError. As the IBBTransferNegotiator has a hard reference to the InBandBytestreamManger and therefore the InBandBytestreamManger instance is not Garbage collected and is still available/active.
So my conclusion: either remove the hard reference to the InBandBytestreamManger from IBBTransferNegotiator or better let the InBandBytestreamManger not clean itself on connectionClosedOnError.