eclipse-ee4j / tyrus

Tyrus
Other
115 stars 37 forks source link

Websocket close with 1006 unless connect by localhost #614

Open glassfishrobot opened 7 years ago

glassfishrobot commented 7 years ago

I am trying to use websocket.

However I can only connect to localhost. Any remote client connecting will result in code 1006 after socket.getBasicRemote().sendText();

My server side is using java. Client side is using javascript. Java is listening on 8080 with glassfish 4.11 (Tried tomcat8 as well). I tested using 2 client and both are able to connect to 8080 with HTTP.

Server side:

@ServerEndpoint("/test")
public class Test {
    final static Logger logger = Logger.getLogger(HelloWorld.class);
    @OnMessage
    public void onMessage(Session session, String message) {
        try {
            logger.info(message);
            session.getBasicRemote().sendText(message);
        } catch (IOException ex) {
        }
    }
}

Client Side:

<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="https://code.jquery.com/jquery-3.2.1.min.js" crossorigin="anonymous"></script>
        <script src="public/vendor/URI.js"></script>
        <script>
            $(document).ready(function(){
                var uri = URI.parse(window.location.href);
                var socket = new WebSocket("ws://"+uri.hostname+":"+uri.port+"/WebSocketServer/test");
                socket.onopen = function(evt){
                    console.log(evt);                        
                }
                socket.onmessage = function(evt){
                    console.log(evt.data);
                }
                socket.onclose = function(evt){
                    console.log(evt);
                }
                $("#click").click(function(){
                    socket.send("asdf");
                })
            })
        </script>
    </head>    
    <body>
        <button id="click"> click </button>
    </body>
</html>

When connecting to localhost, the server is able to send message to client

This is the dump in javascript console (localhost)

test.html:19 Event {isTrusted: true, type: "open", target: WebSocket, currentTarget: WebSocket, eventPhase: 2…}bubbles: falsecancelBubble: falsecancelable: falsecomposed: falsecurrentTarget: WebSocketdefaultPrevented: falseeventPhase: 0isTrusted: truepath: Array(0)returnValue: truesrcElement: WebSockettarget: WebSockettimeStamp: 192.78type: "open"__proto__: Event
test.html:23 asdf

This is the dump when connectin using remote client

test.html:19 Event {isTrusted: true, type: "open", target: WebSocket, currentTarget: WebSocket, eventPhase: 2…}
test.html:26 CloseEvent {wasClean: false, code: 1006, reason: "", type: "close", target: WebSocket…}

Also I can confirm that the server did reply the client by inspecting the packet. The following is a packet captured in another endpoint similar to this

Frame 65: 113 bytes on wire (904 bits), 113 bytes captured (904 bits) on interface 0
Ethernet II, Src: Sonicwal_e1:87:e0 (00:17:c5:e1:87:e0), Dst: Micro-St_ae:a2:00 (44:8a:5b:ae:a2:00)
Internet Protocol Version 4, Src: 192.168.1.33, Dst: 192.168.0.103
Transmission Control Protocol, Src Port: 8080 (8080), Dst Port: 33962 (33962), Seq: 304, Ack: 557, Len: 59
WebSocket
    1... .... = Fin: True
    .000 .... = Reserved: 0x00
    .... 0001 = Opcode: Text (1)
    0... .... = Mask: False
    .011 1001 = Payload length: 57
    Payload
Line-based text data
    {"type":"NORMAL","payload":"sdfasdf joined the channel."}

Please asist

glassfishrobot commented 6 years ago
glassfishrobot commented 7 years ago

@pavelbucek Commented This seems like you have some proxy on the way, which doesn't understand websocket protocol and terminates it after a timeout or initial data.

Please retry on a clean network and let us know whether that helped.

glassfishrobot commented 7 years ago

@anthony-poon Commented Hi,

Thanks for the quick reply.

I tried connecting 2 computer using a crossover and repeated the test. It is still having the same problem so I doubt it is the proxy problem.

This is the packet capture from the host to client

7   1.532965    192.168.2.1 192.168.2.2 TCP 54  8080 → 44809 [ACK] Seq=1 Ack=11 Win=256 Len=0`
9   1.734954    192.168.2.1 192.168.2.2 TCP 60  8080 → 44809 [PSH, ACK] Seq=1 Ack=11 Win=256 Len=6
11  1.739262    192.168.2.1 192.168.2.2 TCP 54  8080 → 44809 [ACK] Seq=7 Ack=12 Win=256 Len=0
12  1.741211    192.168.2.1 192.168.2.2 TCP 54  8080 → 44809 [FIN, ACK] Seq=7 Ack=12 Win=256 Len=0

This is the detailed in the last frame

Frame 12: 54 bytes on wire (432 bits), 54 bytes captured (432 bits) on interface 0
Ethernet II, Src: CeLink_1f:45:0e (a0:ce:c8:1f:45:0e), Dst: Micro-St_ae:a2:00 (44:8a:5b:ae:a2:00)
Internet Protocol Version 4, Src: 192.168.2.1, Dst: 192.168.2.2
Transmission Control Protocol, Src Port: 8080, Dst Port: 44809, Seq: 7, Ack: 12, Len: 0
    Source Port: 8080
    Destination Port: 44809
    [Stream index: 0]
    [TCP Segment Len: 0]
    Sequence number: 7    (relative sequence number)
    Acknowledgment number: 12    (relative ack number)
    Header Length: 20 bytes
    Flags: 0x011 (FIN, ACK)
    Window size value: 256
    [Calculated window size: 256]
    [Window size scaling factor: -1 (unknown)]
    Checksum: 0xbbe1 [unverified]
    [Checksum Status: Unverified]
    Urgent pointer: 0
glassfishrobot commented 7 years ago

@pavelbucek Commented that seems like a connection closed / not accepted by the server - is @OnOpen annotated method on the server endpoint invoked?

it could be even local proxy (read: personal firewall).

Have you tried Tyrus / Java client?

glassfishrobot commented 7 years ago

@anthony-poon Commented I have verified that there is no proxy by checking chrome://net-internals/#proxy. The OnOpen method is being run.

Effective proxy settings

Use DIRECT connections.
Source: SYSTEM

Modified the ServerEndPoint

@ServerEndpoint("/test")
public class Test {
    final static Logger logger = Logger.getLogger(Test.class);
    @OnOpen
    public void onOpen() {
        logger.info("Connection opened");
    }

    @OnMessage
    public void onMessage(Session session, String message) {
        try {
            logger.info(message);
            session.getBasicRemote().sendText(message);
        } catch (IOException ex) {
        }
    }
    @OnClose
    public void onClose(Session session, CloseReason reason) {
        logger.info("Connection closed");
    }
}

Log output of host:

Info:   2017-05-18 11:22:55 INFO  Test:27 - Connection opened
Info:   2017-05-18 11:22:55 INFO  Test:33 - Hello World
Info:   2017-05-18 11:22:55 INFO  Test:40 - Connection closed

The Hello World is from OnOpen of client. The connection close immediately after. The client code using Tyrus client

public class Main {

    private static final String SENT_MESSAGE = "Hello World";

    public static void main(String[] args) {
        try {
            final ClientEndpointConfig cec = ClientEndpointConfig.Builder.create().build();
            ClientManager client = ClientManager.createClient();
            Session s = client.connectToServer(new Endpoint() {
                @Override
                public void onOpen(Session session, EndpointConfig config) {
                    try {
                        session.addMessageHandler(new MessageHandler.Whole<String>() {

                            @Override
                            public void onMessage(String message) {
                                System.out.println("Received message: " + message);

                            }
                        });
                        session.getBasicRemote().sendText(SENT_MESSAGE);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }, cec, new URI("ws://192.168.0.56:8080/WebSocketServer/test"));
            Thread.sleep(1000);
            while (true) {
                s.getBasicRemote().sendText("abc");                
                Thread.sleep(1000);
                System.out.println("Message sent");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Output from client:

java.lang.IllegalStateException: The connection has been closed.
    at org.glassfish.tyrus.core.TyrusSession.checkConnectionState(TyrusSession.java:530)
    at org.glassfish.tyrus.core.TyrusSession.getBasicRemote(TyrusSession.java:212)
    at net.anthonypoon.websocketclient.Main.main(Main.java:50)
glassfishrobot commented 7 years ago

@anthony-poon Commented I printed the stack track for OnClose event

2017-05-19 10:25:11 INFO  Test:54 - java.lang.Thread.getStackTrace(Thread.java:1552)
2017-05-19 10:25:11 INFO  Test:54 - net.anthonypoon.websocket_server.Test.onClose(Test.java:53)
2017-05-19 10:25:11 INFO  Test:54 - sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
2017-05-19 10:25:11 INFO  Test:54 - sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
2017-05-19 10:25:11 INFO  Test:54 - sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
2017-05-19 10:25:11 INFO  Test:54 - java.lang.reflect.Method.invoke(Method.java:498)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.tyrus.core.AnnotatedEndpoint.callMethod(AnnotatedEndpoint.java:520)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.tyrus.core.AnnotatedEndpoint.onClose(AnnotatedEndpoint.java:535)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.tyrus.core.AnnotatedEndpoint.onClose(AnnotatedEndpoint.java:544)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.tyrus.core.TyrusEndpointWrapper.onClose(TyrusEndpointWrapper.java:1251)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.tyrus.core.TyrusWebSocket.onClose(TyrusWebSocket.java:130)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.tyrus.core.ProtocolHandler.close(ProtocolHandler.java:469)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.tyrus.core.TyrusWebSocket.close(TyrusWebSocket.java:260)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.tyrus.core.TyrusWebSocketEngine$TyrusConnection.close(TyrusWebSocketEngine.java:853)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.tyrus.servlet.TyrusHttpUpgradeHandler.close(TyrusHttpUpgradeHandler.java:298)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.tyrus.servlet.TyrusHttpUpgradeHandler.onError(TyrusHttpUpgradeHandler.java:240)
2017-05-19 10:25:11 INFO  Test:54 - org.apache.catalina.connector.InputBuffer$ReadHandlerImpl.processError(InputBuffer.java:614)
2017-05-19 10:25:11 INFO  Test:54 - org.apache.catalina.connector.InputBuffer$ReadHandlerImpl.onError(InputBuffer.java:575)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.http.io.InputBuffer.terminate(InputBuffer.java:1016)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.http.server.Response$SuspendedContextImpl.markCancelled(Response.java:2035)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.http.server.Response$SuspendedContextImpl$SuspendCloseListener.onClosed(Response.java:2112)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.http.server.Response$SuspendedContextImpl$SuspendCloseListener.onClosed(Response.java:2100)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.nio.NIOConnection.invokeCloseListener(NIOConnection.java:955)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.nio.NIOConnection.notifyCloseListeners(NIOConnection.java:828)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.nio.NIOConnection.terminate0(NIOConnection.java:561)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.nio.transport.TCPNIOConnection.terminate0(TCPNIOConnection.java:291)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.nio.transport.TCPNIOTransport.read(TCPNIOTransport.java:609)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.nio.transport.TCPNIOTransportFilter.handleRead(TCPNIOTransportFilter.java:75)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.filterchain.TransportFilter.handleRead(TransportFilter.java:173)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
2017-05-19 10:25:11 INFO  Test:54 - org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
2017-05-19 10:25:11 INFO  Test:54 - java.lang.Thread.run(Thread.java:745)
Adhira-Deogade commented 3 years ago

Interested in this issue. I face the same error code in Jenkins WebSocket.