diff --git a/src/main/java/com/pusher/client/connection/websocket/WebSocketConnection.java b/src/main/java/com/pusher/client/connection/websocket/WebSocketConnection.java index 199c249f..15d41315 100644 --- a/src/main/java/com/pusher/client/connection/websocket/WebSocketConnection.java +++ b/src/main/java/com/pusher/client/connection/websocket/WebSocketConnection.java @@ -271,6 +271,10 @@ public void onClose(final int code, final String reason, final boolean remote) { return; } + if(!shouldReconnect(code)) { + updateState(ConnectionState.DISCONNECTING); + } + //Reconnection logic if(state == ConnectionState.CONNECTED || state == ConnectionState.CONNECTING){ @@ -303,6 +307,12 @@ public void run() { }, reconnectInterval, TimeUnit.SECONDS); } + // Received error codes 4000-4099 indicate we shouldn't attempt reconnection + // https://pusher.com/docs/pusher_protocol#error-codes + private boolean shouldReconnect(int code) { + return code < 4000 || code >= 4100; + } + private void cancelTimeoutsAndTransitonToDisconnected() { activityTimer.cancelTimeouts(); diff --git a/src/test/java/com/pusher/client/connection/websocket/WebSocketConnectionTest.java b/src/test/java/com/pusher/client/connection/websocket/WebSocketConnectionTest.java index ca7869fb..a3943a2c 100644 --- a/src/test/java/com/pusher/client/connection/websocket/WebSocketConnectionTest.java +++ b/src/test/java/com/pusher/client/connection/websocket/WebSocketConnectionTest.java @@ -316,7 +316,37 @@ public void stateIsReconnectingAfterOnCloseWithoutTheUserDisconnecting() throws connection.connect(); connection.onMessage(CONN_ESTABLISHED_EVENT); - connection.onClose(500, "reason", true); + connection.onClose(3999, "reason", true); + + assertEquals(ConnectionState.RECONNECTING, connection.getState()); + } + + @Test + public void stateIsDisconnectedAfterOnCloseWithoutTheUserDisconnectingCode4000() throws InterruptedException, SSLException { + connection.connect(); + connection.onMessage(CONN_ESTABLISHED_EVENT); + + connection.onClose(4000, "reason", true); + + assertEquals(ConnectionState.DISCONNECTED, connection.getState()); + } + + @Test + public void stateIsDisconnectedAfterOnCloseWithoutTheUserDisconnectingCode4099() throws InterruptedException, SSLException { + connection.connect(); + connection.onMessage(CONN_ESTABLISHED_EVENT); + + connection.onClose(4099, "reason", true); + + assertEquals(ConnectionState.DISCONNECTED, connection.getState()); + } + + @Test + public void stateIsDisconnectedAfterOnCloseWithoutTheUserDisconnectingCode4100() throws InterruptedException, SSLException { + connection.connect(); + connection.onMessage(CONN_ESTABLISHED_EVENT); + + connection.onClose(4100, "reason", true); assertEquals(ConnectionState.RECONNECTING, connection.getState()); }