收到“未收到握手响应”。关闭 websocket 后

Posted

技术标签:

【中文标题】收到“未收到握手响应”。关闭 websocket 后【英文标题】:getting "Handshake response not received." after closing websocket 【发布时间】:2015-09-04 19:41:11 【问题描述】:

我正在使用 tyrus websocket 客户端 (1.11) 连接到 websocket。

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

我正在运行本地 wscat 服务器 (wscat --listen) 来测试我的连接。

我的客户端所做的是它连接到 websocket,发送一个文本字符串,然后是二进制负载 (0xb5,0xb2,0xb1,0xb0,0xb1,0xb2,0xc6),然后是另一个字符串,然后断开连接。

这是服务器看到的(也正是我所期望的):

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

注意:进行连接的实体,Monkey 类扩展 Thread 并异步运行,因此某些日志行可能出现故障。

不过,客户端的情况并不那么乐观。虽然日志同意建立了连接,发送了三个块并关闭了连接,但它也给了我一个堆栈跟踪 连接失败,因为没有收到握手响应(请参阅完整日志 @ 987654321@):

...
[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
...

为什么会出现明显的第二次连接尝试? 这是怎么回事?

我输入了几个时间戳来看看实际发生了什么:

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;

我实际得到的结果表明我无法连接(但我确实发送了这些消息,不是吗?)

[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

当我与 ws 进行交易时,连接调用似乎被阻止了。是否因为连接在onOpen 回调结束时关闭而假设出现错误?

【问题讨论】:

能否将依赖版本明确设置为 1.11?看来您可能正在使用旧的东西.. 版本号其实是IDE中显示的,不过我也试试显式版本。 【参考方案1】:

好的,所以似乎在onOpen 回调期间关闭会话确实是WebsocketContainer 感到困惑并认为连接失败的原因。 只是为了测试,我使用getBasicRemote()(同步)发送消息,然后在所有完成后关闭套接字。 我切换到使用 getAsyncRemote() 并在发送所有消息后关闭,现在 wsc 正确报告连接成功。

我想知道阻止回调是否是个好主意?

【讨论】:

【参考方案2】:

不要在onOpen(Session session, EndpointConfig endpointConfig) 中调用Thread.sleep()。使用自己的线程发送消息,ClientManager.connect返回Session对象,使用该对象发送消息。

【讨论】:

以上是关于收到“未收到握手响应”。关闭 websocket 后的主要内容,如果未能解决你的问题,请参考以下文章

为啥我会收到“WebSocket 连接已关闭:代码 = 1000(OK),没有原因”

rxjs/webSocket - 到“ws://localhost:3000/”的 WebSocket 连接失败:连接在收到握手响应之前关闭

Websocket 连接因错误“收到意外的延续帧”而关闭。

与“ws://localhost:3000/”的 WebSocket 连接失败:在收到握手响应之前连接已关闭

“在收到握手响应之前连接已关闭”尝试使用 websockets 将 Angular 与 Spring 连接时

Python websockets keepalive ping 超时;没有收到关闭帧