简体   繁体   中英

getting “Handshake response not received.” after closing websocket

I'm using tyrus websocket client (1.11) to connect to a websocket.

compile 'org.glassfish.tyrus:tyrus-client:1.+'
compile 'org.glassfish.tyrus:tyrus-container-grizzly-client:1.+'

I'm running a local wscat server ( wscat --listen ) to test my connection.

What my client does is that it connects to the websocket, sends a text string followed by a binary load (0xb5,0xb2,0xb1,0xb0,0xb1,0xb2,0xc6), followed by another string and then disconnects.

This is what the server sees (and is exactly what I expect):

listening on port 8666 (press CTRL+C to quit)
client connected
< Ohai, Server!
< �������
< Bye, Server!
disconnected

Note : The entity doing the connection, the Monkey class extends Thread and runs asynchronously so some log lines may be out of order.

Things aren't as peachy on the client side, though. While the logs agree that a connection was made, the three chunks were sent, and the connection was closed, it also gives me a stacktrace that connection failed because no handshake response was received (See the full log here ):

...
[org.glassfish.tyrus.client.TyrusClientEngine] FINE: > Session af609b3f-2978-453f-9758-10351d5ed2af [43 ms]: Sending handshake request:
> GET ws://127.0.0.1:8666
> Connection: Upgrade
> Host: 127.0.0.1:8666
> Origin: 127.0.0.1:8666
> Sec-WebSocket-Key: pGNihDxLIbQqcxvMTBERSQ==
> Sec-WebSocket-Protocol: binary
> Sec-WebSocket-Version: 13
> Upgrade: websocket

[org.glassfish.tyrus.client.TyrusClientEngine] FINE: < Session af609b3f-2978-453f-9758-10351d5ed2af [324 ms]: Received handshake response: 
< 101
< connection: Upgrade
< sec-websocket-accept: EZjq5dEOzWz2q46tKtNlVD8K+mk=
< sec-websocket-protocol: binary
< upgrade: websocket
...
[MONKEY_0] FINER: Session 'af609b3f-2978-453f-9758-10351d5ed2af' opened
[RUNNER] INFO: MONKEY_0 connected
[MONKEY_0] FINER: Sending messages...
[MONKEY_0] FINER: Saying Hi...
[org.glassfish.tyrus.core.TyrusRemoteEndpoint] FINEST: > Session af609b3f-2978-453f-9758-10351d5ed2af [335 ms]: Sending text message: Ohai, Server!
...
[MONKEY_0] FINER: Said Hi. Now Sending binary data...
[org.glassfish.tyrus.core.TyrusRemoteEndpoint] FINEST: > Session af609b3f-2978-453f-9758-10351d5ed2af [342 ms]: Sending binary message
[MONKEY_0] FINER: Binary sent. Saying Bye...
[org.glassfish.tyrus.core.TyrusRemoteEndpoint] FINEST: > Session af609b3f-2978-453f-9758-10351d5ed2af [344 ms]: Sending text message: Bye, Server!
[MONKEY_0] FINER: Messages sent.
[MONKEY_0] INFO: Closing socket.
[org.glassfish.tyrus.core.TyrusRemoteEndpoint] FINE: Close public void close(CloseReason cr): CloseReason[1000,Bye]
...
[MONKEY_0] FINER: Session 'af609b3f-2978-453f-9758-10351d5ed2af' closed (Bye)
[RUNNER] INFO: MONKEY_0 disconnected
[MONKEY_0] SEVERE: Unable to connect to 'ws://127.0.0.1:8666'
javax.websocket.DeploymentException: Handshake response not received.
    at org.glassfish.tyrus.client.ClientManager$3$1.run(ClientManager.java:691)
    at org.glassfish.tyrus.client.ClientManager$3.run(ClientManager.java:712)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at org.glassfish.tyrus.client.ClientManager$SameThreadExecutorService.execute(ClientManager.java:866)
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
    at org.glassfish.tyrus.client.ClientManager.connectToServer(ClientManager.java:511)
    at org.glassfish.tyrus.client.ClientManager.connectToServer(ClientManager.java:373)
    at com.redacted.webmonkey.monkey.Monkey.connect(Monkey.java:90)
    at com.redacted.webmonkey.monkey.Monkey.run(Monkey.java:47)
Caused by: java.lang.InterruptedException
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos(AbstractQueuedSynchronizer.java:1039)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1328)
    at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:277)
    at org.glassfish.tyrus.client.ClientManager$3$1.run(ClientManager.java:666)
    ... 9 more
...
[RUNNER] SEVERE: 'MONKEY_0' failed. Error: Cannot connect
...

Why is there an apparent second attempt to connect? What is going on here?

I threw in a few timestamps to see what's actually going on:

Session s = null;
try {
    LOG.d("(%d) attempting to connect", System.currentTimeMillis());
    WebSocketContainer wsc = ContainerProvider.getWebSocketContainer();
    s = wsc.connectToServer(this, uri);
    LOG.d("(%d) Connected", System.currentTimeMillis());
} catch (Exception e) {
    LOG.e("(%d) Unable to connect to '%s'", System.currentTimeMillis(), uri);
    e.printStackTrace();
}

LOG.d("(%d) Session id : %s", System.currentTimeMillis(), s == null ? null : s.getId());
return s != null;

What I actually get suggests that I cannot connect (Yet I did and sent those messages, didn't I?)

[MONKEY_0] FINER: (1441396510763) attempting to connect
[MONKEY_0] FINER: (1441396511068) Session '4c0b1f6e-de7e-471d-a801-f807895c4a0b' opened
[MONKEY_0] FINER: (1441396511079) Session '4c0b1f6e-de7e-471d-a801-f807895c4a0b' closed (Bye)
[MONKEY_0] SEVERE: (1441396511080) Unable to connect to 'ws://127.0.0.1:8666'
[MONKEY_0] FINER: (1441396511081) Session id : null

It looks like the connect call is blocked while I transact with the ws. Does it assume there was an error because the connection is closed at the end of the onOpen callback?

OK, so it seems that closing the session during the onOpen callback is indeed the reason why the WebsocketContainer gets confused and thinks the connection failed. Just for testing, I was sending the messages using the getBasicRemote() (synchronous) and then closing the socket after all were done. I switched to using getAsyncRemote() and closing after all messages were sent and now the wsc correctly reports success in connection.

I wonder if it's a good idea to block on the callback?

Do not call Thread.sleep() in onOpen(Session session, EndpointConfig endpointConfig) . Use your own thread to send message, ClientManager.connect return Session object, use this object to send messages.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM