Spring @ClientEndpoint websocket client does not detect network disconnect due to cable unplug. I also have implemented a ping/pong mechanism. Can someone please help me out with what's going on? However I see following exception after reconnecting the cable, FYI, all setting are into default. Also I am connecting to a 3rd party remote endpoint where do not have any control.
xxxxxException: closed with code : CLOSED_ABNORMALLY reason: CloseReason: code [1006], reason [java.io.IOException: Connection reset by peer]
at xxxxxx.onClose(WSClient.java:xx)
@ClientEndpoint
public class WSClient {
private Session session;
private int i = 0;
@OnOpen
public void open(Session session) {
System.out.println("Connected to the server");
this.session = session;
}
@OnClose
public void close(Session session, CloseReason closeReason) {
System.out.println("connection closed " + closeReason.getReasonPhrase());
}
@OnError
public void error(Session session, Throwable t) {
System.out.println(session.getId());
System.out.println("Error in connection " + t.getMessage());
}
@OnMessage
public void message(Session session, String message) {
System.out.println("message received: " + message + " " + i++);
}
public void send(String message){
try {
if(session.isOpen()) {
this.session.getBasicRemote().sendPing(ByteBuffer.wrap(message.getBytes()));
System.out.println("socket is open " + i++);
} else {
System.out.println("socket closed");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Component
public class ClientApp implements ApplicationListener<ApplicationReadyEvent> {
private void startConnection() throws Exception {
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
WSClient client = new WSClient();
container.connectToServer(client, new URI("ws://wshost:8080/ping"));
while (true) {
client.send("ping");
TimeUnit.SECONDS.sleep(3);
}
}
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
try {
startConnection();
} catch (Exception e) {
System.out.println(e);
}
}
}
This issue can be resolved by adding below code to WSClient
.
@OnMessage
public void pongMessage(Session session, PongMessage msg) {
LOGGER.debug("Pong message received: " + Instant.now());
//schedule a timeout task, and raise an event or so if timed out.
}
The above snippet will be invoked when remote endpoint sends a pong message as a respond to the ping message sent. Basically there will be two methods annotated with @OnMessage
, one to received the user message payload and another pong message payload sent by the framework.