PING / PONG on websocket is considered a back-channel. A form of health check.
Its supposed to be automatically responded to (similar to ICMP echo, SPDY ping, HTTP/2 ping, etc...).
Many implementations do not support sending a pong.
This is because sending a pong with a different payload (something that becomes possible when you expose .sendPong()) is often interpreted as a failed PING/PONG pair.
The jetty exposure is because of JSR-356, aka javax.websocket. (This API has many small issues. the next iteration will hopefully soften the numerous papercuts present)
Know this, Jetty will *ALWAYS* respond to a PING it receives with a PONG of the same payload (as soon as it has parsed the PING, it shoves the PONG at the front of the frame queue for outgoing reply)
Therefore, using javax.websocket.RemoteEndpoint.sendPong() will result in a naked pong for a unsent ping.
The PING/PONG is also out-of-band, meaning it can exist in the middle of other messages.
Since the APIs for notifications are supposed to be thread-safe, this out of band behavior of websocket control messages means that if you were handling a large message, consisting of many websocket frames (fragments), we couldn't notify you of the PING
or PONG until your endpoint is done handling the message. (this is especially true of Decoded or Stream based message handling).
As for keeping a connection alive, that's a facility of idle timeout.
If you want to track latency, send a PING with a sequence indicator + timestamp. in your onPong, compare the sequence indicator (if desired), and the timestamp for latency. Also know that the latency you see here can be skewed by a large frame. (if a
frame is in progress, nothing else can be sent until that frame is completed).
If you want to discover network issues faster (such as a mobile device going out of coverage), then use a PING/PONG, the result will be a non-response, or have ridiculous latency, or even cause an IO error with an abnormal close.