-
Notifications
You must be signed in to change notification settings - Fork 394
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WICKET-6954] implement server side heart-beat + client reconnection in case of inactivity #499
base: wicket-9.x
Are you sure you want to change the base?
[WICKET-6954] implement server side heart-beat + client reconnection in case of inactivity #499
Conversation
…in case of inactivity
/** | ||
* Boolean used to determine if ping-pong heart beat will be used. | ||
*/ | ||
private boolean usePingPongHeartBeat = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the difference with useHeartBeat
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems ping-pong is designed for the following use case:
-server sends pings to all remote client peers and clients respond with a pong
-server can use this to determine some connection is dead and kill it
-it seems the standard does not include a public onping at client side. Thus browser might respond to this with a pong. Chrome responds with a pong but something like
ws.onping = function() {}
is not called.
Some implementations defines "onping" at client side. See
https://github.com/websockets/ws#how-to-detect-and-close-broken-connections
I have include a class that starts a ping-pong scheduler. But this can't be used a client side in order to reconnect. This uses usePingPongHeartBeat flag.
I have included another timer that send special byte array... This one uses useHeartBeat and is the one used to reconnect broken web-scoket
Not sure if we should keep ping-pong timer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/** | ||
* A {@link IWebSocketMessage message} with Pong message data | ||
* | ||
* @since 6.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not really
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True. Copy and waste
* | ||
* @since 6.0 | ||
*/ | ||
public class PongMessageMessage extends AbstractClientMessage |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why double Message
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just tired programmer working during weekends :-)
url += '&wicket-ajax-baseurl=' + encodeURIComponent(WWS.baseUrl); | ||
url += '&wicket-app-name=' + encodeURIComponent(WWS.appName); | ||
|
||
console.log(url); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
debug leftover
clearTimeout(this.pingTimeout); | ||
// Set a timeout in order to check ping received | ||
this.pingTimeout = setTimeout(() => { | ||
this.ws.close(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't expect to see ws.close()
here.
IMO the heartbeat should attempt to send a PING message. If the sending fails or PONG does not come in N millis then try to reconnect M times.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no API at server side for this (onPing). I close connection => then recreated it that same way as when page was created => trigger a ConectedMessage with reconnect = true. This I plan to use in our app for delivering things to client what we failed not delivered because connection was gone. This is not a fake scenario. It is happening to us (some progress blocking dialog is staying in page sometimes because connection is broken and events fail to reach client).
|
||
@Override | ||
public void terminate(String reason) { | ||
close(-1, "abnormally closed"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setAlive(false)
@@ -79,7 +122,7 @@ public IWebSocketConnection sendMessage(byte[] message, int offset, int length) | |||
protected abstract void onOutMessage(String message); | |||
|
|||
/** | |||
* A callback method that is called when a text message should be send to the client | |||
* A callback method that is called when a text message should be sent to the client |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think d
was correct
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
true... I think IDE just fooled me.
|
||
@Override | ||
protected void onOutMessage(byte[] message) { | ||
messageReceived.set(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this test should call only the old callback method.
This method body should be empty or throw an Exception if it is called by mistake.
{ | ||
if (LOG.isDebugEnabled()) | ||
{ | ||
LOG.debug("Sending unidirectional pon for connection {}", getKey()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pong
|
||
import javax.websocket.EndpointConfig; | ||
import javax.websocket.MessageHandler; | ||
import javax.websocket.PongMessage; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still don't understand how JSR 356 spec makes use of javax.websocket.PongMessage
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Server pings client --> client implementation answers with a pong --> specification does not force client to offer a onping, which is BAD, because we can't use it for reconnect timeout thing :-(. At least this is what I understood after googling around
@martin-g many thanks for your review. I will iterate on PR ASAP |
@martin-g
I have tried to use ping-pong approach but I don't know how to implement client side reconnect using it: it seems there is no any "onping" at client side. I have added a second approach were server send some small binary message as "ping" and client side use it as heartbeat to determine server is still there. In case of "disconnection", client will try to reconnect.
There still might be quite a bit of work to do in this PR or maybe use a different approach?