I have faced similar issue in a project and after investigation it was found that it happens when using Stream Resumption feature (Stream Management XEP-0198).
If stream resumption is enabled when starting a new stream, Openfire will not immediately mark the user as Offline, instead it's session will be marked in Detached state. So the client app can resume the stream again without having to do full login.
If you will not use Stream Resumption, user will immediately become offline.
When enabling Stream Management, if client sends following packet, resumption feature is enabled on the stream.
<enable xmlns='urn:xmpp:sm:3' resume='true'/>
For this packet, server acknowledges by sending back:
<enabled xmlns='urn:xmpp:sm:3' id='some-long-sm-id' resume='true'/>