powered by Jive Software

Expose API in Smack to do XEP-0198 server ping


#1

I’d like to use the 0198 ack mechanism to ping the server, as a light-weight alternative to XEP-0199.

The current API exposes XMPPTCPConnection.addStanzaAcknowledgedListener() which allows to track individual stanzas and requestSmAcknowledgement() to send a “ping” to the server.

However, if there were no actual stanzas transmitted since the last <r/>, the StanzaAcknowledgedListener won’t have any stanzas to acknowledge, and so it won’t be called.

I propose the following changes:


#2

Is there any reason not to design this a high level API, e.g.

SmackFuture<Long> XMPPTCPConnection.requestServerSmHeight()

?


#3

If you go high-level, the actual value of @h doesn’t play a role. The important thing is to ensure that the server actually does respond to the specific I send, so that I can measure the RTT latency. Example:

  • Smack sends <r/> on its own behalf
  • Some time passes without new stanzas
  • I send an <r/> via requestServerSmHeight() (the anticipated @h value is the same)
  • The <a/> corresponding to the first <r/> arrives, so the Future succeeds prematurely
  • The second <a/> arrives in silence.

Ideally, I want something like a blocking/nonblocking XMPPTCPConnection.measureServerLatencyOrTimeout(int timeout_ms) which automatically decides to use 0198 on enabled sessions or PingManager otherwise.


#4

Maybe, but is available anyways and it doesn’ hurt to make it avaialble via the Future.

Ok, you didn’t not mention that this was a requirement. Then, of course, due to how SM <r/> and </a> are designed, you probably can not use the API is suggested.

So your use case is to measure the client to server latency? Is there any reason to not simply use always XMPP pings (XEP-0199)? It appears that would be much simpler and avoid a lot of complexity compared to abusing Stream Management requests if available and fallback to XEP-0199 approach.


#5

I think I have to correct myself here slightly: It should probably be possible to implement the requestServerSmHeight() method so that it yields the result of the <a/> that is triggered as result of the method invocation.


#6

Okay, so now you got me. I should have rolled back from “I try to forward-port the old smack3-based mess into a new smack4-based mess” to whatever I actually want to achieve.

My ultimate goal is to measure/probe the health of the connection as follows:

  • after a certain configurable interval without receiving any data from the server (typically 15mins), I want to probe the connection:
    • send an <r/> or alternatively a <ping>
    • if it is responded to within another configurable interval (typically 60s), everything is alright
    • if no response comes in, fire a callback that does the instantShutdown() + reconnect game
  • the probe handler should be delayed by each incoming packet on the connection (stanza, nonza or even whitespace)

#7

That sounds nearly exactly like what PingManager already does (minus using SM <r/>s).

Is there any reason, besides saving a few bytes for the ping/pong elements, for using stream mangement elements for that?


#8

You are probably right. I know I had very high hopes on using SM pings instead of <ping> back then, but currently I can’t come up with really plausible reasons for that.


#9

After having a look at PingManager, there are some interesting details I’d like to know more about:

  1. It will attempt to ping the server three times in a row, with 1s between. Why is that needed, as opposed to just sending one ping? It’s not like the additional traffic will somehow add more pressure to the connection :wink:

  2. By default, PingManager will ping the server every 30 minutes (with three pings), but it won’t perform any action if those pings time out / throw exceptions. I understand how this is useful to keep the connection running, but it is inconsisten w.r.t. the configuration: either you shouldn’t ping by default and let the client enable pinging and provide a handler, or you should have a default action that resets the connection when no handlers are registered by the client.