WebSocket Client Reconnect

Another new feature was recently added to Tyrus (Java API for WebSocket Reference Implementation): Client ReconnectHandler. Some client use cases require almost persistent client-to-server connection and don’t really care about lower layer issues, like unstable internet connection.

Tyrus Client now include possibility of registering ReconnectHandler, which can help with these scenarios. Let’s see ReconnectHandler declaration:

1
2
3
4
5
6
7
8
9
10
public class ReconnectHandler {
public boolean onDisconnect(CloseReason closeReason) {
return false;
}
public boolean onConnectFailure(Exception exception) {
return false;
}
}

Method onDisconnect is executed whenever client endpoint @OnClose annotated method is called, method onConnectFailure is executed whenever client has some troubles connecting to remote endpoint (network issues, server returning HTTP Status 500, …). Both methods can return boolean value, which indicates whether client should try to reconnect or not.

It is perfectly fine to wait in any of these methods for some time – I would recommend it for onConnectFailure, because there usually is some reason for network failure and repeating requests without any delay can prolong them or even make them worse. Also I would recommend include some kind of counter, which would set the number of reconnect attempts.

Example implementation could look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
ClientManager client = ClientManager.createClient();
ClientManager.ReconnectHandler reconnectHandler = new ClientManager.ReconnectHandler() {
private int counter = 0;
@Override
public boolean onDisconnect(CloseReason closeReason) {
counter++;
if (counter <= 3) {
System.out.println("### Reconnecting... (reconnect count: " + counter + ")");
return true;
} else {
return false;
}
}
@Override
public boolean onConnectFailure(Exception exception) {
counter++;
if (counter <= 3) {
System.out.println("### Reconnecting... (reconnect count: " + counter + ") " + exception.getMessage());
// Thread.sleep(...) or something other "sleep-like" expression can be put here - you might want
// to do it here to avoid potential DDoS when you don't limit number of reconnects.
return true;
} else {
return false;
}
}
};
client.getProperties().put(ClientManager.RECONNECT_HANDLER, reconnectHandler);
client.connectToServer(...)

Comments:

Hi Pavel
you said "Method onDisconnect is executed whenever client endpoint @OnClose annotated method is called". But is it also called when the server machine crashes, is it also called when the JVM process on the server crahsed and it it also called when the network crashes (hardware cable or software)? In all these use cases the @OnClose method is not called. I could try the implementation but would also like to know how it "should" work from a specification perspective.

Regards
Alain

Posted by guest on April 03, 2014 at 10:35 AM CEST #

Hi Alain,

in all of cases mentioned, @OnClose should be called on client side - when TCP connection is broken, client needs to be notified - @OnClose is called and CloseReason should be 1006: Closed abnormally. See https://tools.ietf.org/html/rfc6455#section-7.4.1 for more details.

If you have any testcase which proves me wrong, please retest it with recent Tyrus version (1.5 or 1.6-SNAPSHOT) and if you can still reproduce it, file a new issue at https://java.net/jira/browse/TYRUS and attach that testcase or at least description which would allow me to recostruct it.

Thanks!
Pavel

Posted by Pavel on April 03, 2014 at 10:41 AM CEST #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Pavel Bucek

Search

Categories
Archives
« July 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  
       
Today