Detecting Connection loss in sleekxmpp

817 views
Skip to first unread message

Harish Vishwanath

unread,
Jul 19, 2012, 9:16:55 AM7/19/12
to sleekxmpp-...@googlegroups.com
Hello

I am using sleekxmpp to transfer some data over XMPP. I was testing for a connection loss scenario and this is what I found:

- sleek detects connection loss after a fairly long time (more than a minute?)
- During this time, I still see SEND messages in the debug log where the message stanza has been transmitted.
- It then attempts to reconnect every second.
- If the connection is regained after some attempts, these messages are not transmitted/received, suggesting that there is no buffering happening inside the library.

I would like to detect these connection losses, and take appropriate steps to persist the data.

How can I detect this?


Regards,
Harish

Lance Stout

unread,
Jul 19, 2012, 1:02:11 PM7/19/12
to sleekxmpp-...@googlegroups.com
> - sleek detects connection loss after a fairly long time (more than a minute?)

This would be the result of using a socket in blocking mode -- it waits until the OS says the connection is dead, but TCP tends to try to keep connections alive as long as possible. I'd prefer to use non-blocking sockets because of this, but it will take some work.

> - It then attempts to reconnect every second.

There should be a backoff so that it doesn't do that every second. Which version are you using?

> - If the connection is regained after some attempts, these messages are not transmitted/received, suggesting that there is no buffering happening inside the library.

Right, if the socket accepts the data, then its removed from the send queue because it is up to the OS at that point. If not, the send queue is still flushed on disconnect since Iq stanzas mess things up (ie, sending results from previous session in the new one).

> I would like to detect these connection losses, and take appropriate steps to persist the data.

Your best bet is to use the XEP-0198 plugin which is meant to solve this exact issue (with session resumption). Hopefully you are able to use a server which supports it. If not, you can still look at the source for it to see how the buffering there works.

If your server doesn't support XEP-0198, but the other clients you're sending messages to support XEP-0184 for message receipts, those can be used to manage a buffer of sent messages.

If neither of those apply, then using XEP-0199 for pings with a small timeout should give you faster notification that the connection has gone stale.


-- Lance

Harish Vishwanath

unread,
Aug 7, 2012, 11:22:41 AM8/7/12
to sleekxmpp-...@googlegroups.com
Hello

After some research, I figured that opening a telnet connection to the XMPP server on Port 5222 is a quicker way to find out connection losses.

But once I detect a connection loss, I want to notify the library that the connection is unavailable and re attempts have to be made, while I buffer the data that I want to transfer on persistent storage.

I am not sure how to notify the library that such an event has happened. I went through xmlstream.py code, and have a feeling that a state machine change would help, but not sure how to do this.

Your help is greatly appreciated.

Regards,
Harish

Lance Stout

unread,
Aug 7, 2012, 1:01:11 PM8/7/12
to sleekxmpp-...@googlegroups.com
> I am not sure how to notify the library that such an event has happened. I went through xmlstream.py code, and have a feeling that a state machine change would help, but not sure how to do this.

I would try using self.disconnect(reconnect=True, send_close=False)

BRIAN BEGGS

unread,
Aug 7, 2012, 1:03:20 PM8/7/12
to sleekxmpp-...@googlegroups.com
Harish,

I don't think that checking the port via telnet is a good way to determine if the xmpp session is still established. 

The TCP connection could abandoned for the XMPP connection but you could still possibly be able to telnet to the host.  Using telnet or opening another socket to the host does not tell you anything about the socket that is currently open to that host for the XMPP connection.  

We use xep-0199 to detect this state and it has worked well for us to this point.  Is it instantaneous?  No, but it works reliably.

and Lance has the right answer here:
Your best bet is to use the XEP-0198 plugin which is meant to solve this exact issue (with session resumption). Hopefully you are able to use a server which supports it. If not, you can still look at the source for it to see how the buffering there works.

If your server doesn't support XEP-0198, but the other clients you're sending messages to support XEP-0184 for message receipts, those can be used to manage a buffer of sent messages.

If neither of those apply, then using XEP-0199 for pings with a small timeout should give you faster notification that the connection has gone stale.

Opening a new port to test your connection is the incorrect way to go about this.

Brian

Harish Vishwanath

unread,
Aug 8, 2012, 12:31:57 PM8/8/12
to sleekxmpp-...@googlegroups.com
Hi Brian/Lance

Thanks for your suggestions. XEP0199 definitely solves my need. I had misunderstood that XEP0199 responses will be sent by the receiving XMPP Node, but after reading through the specs saw that if bare JID is given as the target, the server responds on behalf of the target node.

Thanks again for all the help.

On another note :  How does sleekxmpp know when the socket has gone stale and reattempts a connection? I tested this today, and I never saw connection reattempts even after I disconnected from the network for as long as 30 minutes.

Regards,
Harish

BRIAN BEGGS

unread,
Aug 8, 2012, 12:59:19 PM8/8/12
to sleekxmpp-...@googlegroups.com
Under the current implementation the best way to know if an established TCP session has gone stale is to send data over the socket.  If the socket times out it will raise an exception and the reconnection process will start.
Reply all
Reply to author
Forward
0 new messages