Bug 57762

Summary: WebSocket client doesn't detect forceful connection failures
Product: Tomcat 8 Reporter: palmercox
Component: WebSocketAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P2    
Version: 8.0.20   
Target Milestone: ----   
Hardware: PC   
OS: All   

Description palmercox 2015-03-26 00:32:07 UTC
It appears that the WebSocket client can't detect when a connection is forcefully closed. Given the following example program:

public class App2 {
    @ClientEndpoint
    public static class Client {
        @OnClose
        public void onClose() {
        	System.out.println("CLOSED");
        }
        
        @OnError
        public void onError(Throwable t) {
        	System.out.println("ERROR: " + t);
        }
    }

    public static void main(final String[] args) throws Exception {
        final WebSocketContainer container = ContainerProvider.getWebSocketContainer();
        System.out.println("Container: " + container);
        container.connectToServer(
                Client.class,
                URI.create("ws://echo.websocket.org/"));
        Thread.sleep(Long.MAX_VALUE);
    }
}

I then modified /etc/hosts so that echo.websocket.org resolved to localhost. I then set up an SSH tunnel to direct local port 80 to echo.websocket.org (which is 174.129.224.73):

sudo ssh me@someserver -L 80:174.129.224.73:80

I then started the program. It connected. Next, I killed the SSH session. Neither the onClosed on onError methods were invoked.

When I tested the same program running on Tyrus 1.10, however, onClose was invoked with a CloseReason 10006 - Closed Abnormally.

I think the Tyrus behavior is correct - the socket is dead and the program should be notified.
Comment 1 palmercox 2015-03-26 00:36:12 UTC
I tested this on Tomcat 8.0.20.
Comment 2 Remy Maucherat 2015-03-26 09:30:55 UTC
The NIO2 code that the client uses looks ok to me (WsFrameClient) and should work unless there's a JVM or platform issue. If the JVM doesn't report that the socket is gone using the failed of the completion handler, then nothing is going to happen and it would be the behavior you see.

Although this should be tested to make sure this is indeed the explanation, it's possible there's no Tomcat bug to fix here.
Comment 3 palmercox 2015-03-26 14:24:02 UTC
For reference, I tested on Mac OS X 10.10.2 and Java 1.8.0_40. I haven't had a chance to check if there is a JVM issue.
Comment 4 Mark Thomas 2015-03-28 21:55:06 UTC
Interesting. The NIO2 code reports a dropped connection as a successful read for EOF. Not what was expected. This is now correctly handled in trunk, 8.0.x (for 8.0.22 onwards) and 7.0.x (for 7.0.62 onwards).