BOSH connection not closed while disconnect()

As per the code Smack/XMPPBOSHConnection.java at master · igniterealtime/Smack · GitHub

at line number 290 there should be a client closing code

but the client close code only exists in the connect() function and no where else it is called

this leads the client to stay connected until the main thread terminates

Introduce a private function saying close()

and put


if (client != null) {

client.close();

client = null;

}


and call it at both connect() as well as shutdown() functions

I’ve just moved the ‘close()’ code into the shutdown() block. Please try the latest snapshot and report back how it works.

Opps, it throws an exception…:frowning:

I went through the jbosh-0.8.0 code

Instead of doing client.close() we need to do client.disconnect()

put the client.diconnect() code in the shutdown() block instead

Which exception is thrown, please with stacktrace?

As far as I can see from the source, disconnect() will also not terminate the connection.

I first thought that simply changing JBOSH’s close() to call dispose with null would be the better approach. But then I read

  • Forcibly close this client session instance. The preferred mechanism

  • to close the connection is to send a disconnect message and wait for

  • organic termination.

So it appears there is an organic termination mechanism that is will happen once the session is disconnected. I assume that’s simply the BOSH HTTP connections running in a timeout and being recreated. Which means everything is ok as it is.

Yes I tried that also, it jbosh does not allow null which will again throw another exception

so what I did is I overrided the disconnect() from AbstractXMPPConnection and I call super.disconnect()

@Override

public void disconnect() {

synchronized (client) {

try {

client.disconnect();

} catch (BOSHException e) {

}finally{

super.disconnect();

}

}

}

which will do the jbosh disconnect as well as the XMPP disconnect unfortunately 2 unavailable presence will be sent

And I swallow the Exception in shutdown… probably a semi standard workaround

try {

if (client != null) {

client.close();

}

} catch (Exception e) {

// Ignore

} finally {

client = null;

}

but BOSHClient.disconnect(ComposableBody) is already called by XMPPBOSHConnection.shutdown(), which is called by AbstractXMPPConnection.disconnect(). So what you did seems a bit redundant.

Smack/XMPPBOSHConnection.java at master · igniterealtime/Smack · GitHub

AbstractXMPPConnection.disconnect() does calls XMPPBOSHConnection.shutdown()

but the current shutdown does not have either disconnect() or close()

I am suspecting .close() never happens even we call disconnect()

and may in control inside the jbosh code after some thread cleanup

therefore I want to force close the connection in shutdown()… but I need to check on which state the close() implicitly happening in jbosh

I swear when I looked at it that one day, XMPPBOSHConnection.shutdown() had a call to BOSHClient.disconnect(). But now I can’t find it anymore. Maybe an effect of the sleep deprivation I experience.

Anyway, thanks for commit back.

So why not simply add

try {

client.disconnect()

} catch (BOSHException e) {

LOG.log(Level.warning, “Exception while disconnecting bosh client”, e)

}

to XMPPBOSHConnection.shutdown()

assuming that this will organically terminate the HTTP/TCP connections too (after some time).

I hope so

as per the code line 716 jbosh/BOSHClient.java at master · igniterealtime/jbosh · GitHub

unless httpSender.destroy(); is invoked, it will keep on sending an empty http-bind requests (each 20 seconds I assume)

which makes the openfire server to get confused to send stanza or create another anonymous user

so there must be a option acquire a callback listener something like “ready to terminate the connection” through which we can completely dispose

when I program I am getting <body type=‘terminate’ xmlns='http://jabber.org/protocol/httpbind’/> after which I was expecting the thread to be stopped

but I am seeing in debug log it keeps on sending

it seems the proper way to disconnect is XEP-0124: Bidirectional-streams Over Synchronous HTTP (BOSH)

therefore we need to override the public synchronized void disconnect(Presence unavailablePresence) function in AbstractXMPPConnection

and put the following code

try {

client.disconnect( ComposableBody.builder().setPayloadXML(unavailablePresence.toXML().toString()).setAttribute(BodyQName.create(BOSH_URI, “sid”), sessionID).build());

} catch (Exception e) {

//Ignore

}

shutdown();

callConnectionClosedListener();

but unfortunately callConnectionClosedListener() is not visible … is it possible we can make it public??