I'm experiencing lost of packets between client and server very often. I suppose that it's because of the intermitent lacking of mobile network. Based on this scenario the server can think that the client connection is still alive when really the client has abruptly lost the connection to the server.
So I have implemented the XEP 0199 Ping on the client side. The clients send a ping packet every 30 seconds. The question is how could I adjust timeout ping on the server side? So if any client does not send a ping packet before this time the server kills the connection and forces the client to reconnect. Or which would be the best approach?
Thanks in advance.
Added by Artur Hefczyc over 5 years ago
Please note, there is no way the server can force the client to reconnect. If the server does not receive a ping from a client for some time, it may mean, that the connection is broken but, most likely neither the client or the server is aware of it. So killing the connection on the server side does not change anything. The client is still and will still be unaware of the broken connection.
The best correct approach to the problem is to ping the server from a client periodically and if the client does not receive a response within required timeout it tries to reconnect as it means that the connection is most likely broken. Then the client should reconnect to the server with the same resource. When the server sees a new connection from a user for the same resource it knows that the old connection is broken so it invalidates it and allows the user to communicate on the new connection.
However, it does not solve the problem completely. As it may happen that there are messages sent in the meantime between the server and the client between the ping was send without a response and the timeout run out. To cover this case as well you should implement in your client Stream Management XEP-0198 which allows for packet delivery confirmation and fast reconnecting to the server.
Added by Mauro Carrio over 5 years ago
Ok, I understand. We have already scheduled the stream management implementation on clients.
I was looking into ClientConnectionManager.java and there is a maxInactiveTime hardcoded, so if I change that value to 30 seconds for example, actually the clients are sending a ping staza every 20 seconds. If the server reaches the 30 seconds without any client activity It will kill the connecion.
As a workaround until we have finished the stream management implementation, I think that killing the connection on the server side as soon as posible is really very important. An example of this would be that if a client looses connection because of no internet coverage, the server until 24 hours later will think that the connection is alive, and it will deliver all packets including chat messages and of course the client will never notice this.
Added by Artur Hefczyc over 5 years ago
Yes, Stream Management is independent of the lower level protocol used. It works the same way for Bosh, standard XMPP, Websockets and whatever else will come. It works above the transport layer. The XEP is also supported by our client side library which also works for web client, android, stand-alone, etc....
Added by Matthew M over 5 years ago
Hi Tigase Team,
After a bit more thoughts on the XMPP Ping, as well as the getMaxInactiveTime() in ClientConnectionManager.java (thanks to Mauro Carrio), I wonder if Tigase can also initiate a Ping stanza to client.
More specifically, does Tigase have server-to-client Ping as specified in http://xmpp.org/extensions/xep-0199.html#s2c ?
This could be useful that the client's connection is broken, and for some reason the client (mobile) app is kill, it is never going to reconnect anytime soon. However, the server may still think this connection is alive, and as this post stated, it could be 10 minutes or even longer for the server to eventually detect this connection is bad and should be killed. Any packets during this time will still be "delivered" by the server to the client -- of course it will never be received, and likely no error reporting (or I am not aware of)
In this case, the only way for server to quickly close this connection is to let server initiate Ping periodically to the client, and kill the connection if there is no respond. Does Tigase has such mechanism? Is there something related to the watchdog thread in Connection Manager?
By the way, is there any example to "fetch" and "view" such statistics about a ConnectionManager component?
Many thanks in advance!
Added by Wojciech Kapcia over 5 years ago
Currently there is no such functionality.
However if you want to improve detection of broken connection (for regular socket connections) you could tweak TPC keepalive settings of the OS, you can find more for example: Using TCP keepalive to Detect Network Errors