码头升级(9.2.24-> 9.4.10)失败,并带有websocket(UpgradeException)

时间:2018-06-20 07:54:14

标签: websocket embedded-jetty jetty-9

我正在将我们的码头从9.2.24升级到9.4.10,以使该应用程序可与websockets广泛兼容。

我有一个现有的测试(junit),该测试可设置嵌入式码头,向其注册其余资源和websocket servlet,然后进行测试以查看是否可以访问它们。

当码头版本为9.2.24时,该测试效果很好。尝试使用完全相同的代码移至版本9.4.10 失败,并显示

java.io.IOException: Connect failure
    at org.eclipse.jetty.websocket.jsr356.ClientContainer.connect(ClientContainer.java:232)
    at org.eclipse.jetty.websocket.jsr356.ClientContainer.connectToServer(ClientContainer.java:255)   
...
Caused by: org.eclipse.jetty.websocket.api.UpgradeException: 400 Bad Request
    at org.eclipse.jetty.websocket.client.WebSocketUpgradeRequest.onComplete(WebSocketUpgradeRequest.java:522)
    at org.eclipse.jetty.client.ResponseNotifier.notifyComplete(ResponseNotifier.java:193)

服务器端的websocket定义基于JSR356规范(即扩展了 EndPoint )。用于访问websocket的websocket客户端也基于javax.websocket(即 ContainerProvider.getWebSocketContainer()。connectToServer(Endpoint instance ...))-其中,websocket容器实际上是一个码头...

服务器设置完美。问题仅在尝试访问websocket时出现。我已经调试,找不到客户端启动和发送websocket请求的方式的任何区别。特别是,请求中的“升级”标头设置为“ websocket”,符合预期。

所以我只能假设问题出在嵌入式码头中Websocket资源的注册方式。我调试了 working 流(使用9.2.24),并发现了码头最早接受连接的最早位置(AbstractConnection的选择器线程之一)。但是出于某种原因,在使用9.4.10时,我无法达到websocket的目的

我已经阅读了一些资源和特殊问题(例如this question),但找不到任何可以帮助我解决该问题的内容。 我死定了。

以下是服务器注册相关代码中的关键元素(我也有另一个rest资源和websocket资源):

// web socket
ServletContextHandler wsContext = new ServletContextHandler(ServletContextHandler.SESSIONS);
wsContext.setContextPath("/ws_api");
ServerContainer container = WebSocketServerContainerInitializer.configureContext(servletContextHandler);
container.addEndpoint(new BasicServerEndpointConfig(container.getClient(), endpointClassObject, path)

// rest handler
ServletContextHandler restContext = new ServletContextHandler(ServletContextHandler.SESSIONS);
restContext.setContextPath("/rest_api");
...
ServletHolder sh = new ServletHolder(...);
restContext.addServlet(sh, "/*");

final HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[]{wsContext, restContext, new DefaultHandler()});
server.setHandler(handlers);

帮助...

更新(每个Joakim Erdfelt请求的其他信息):

我在BP中 onComplete()方法的 HTTPConnection 类中,从 _channel._fields 对象I中获取请求标头得到:

enter image description here

响应对象的状态为200(而不是预期的101):

enter image description here

我的终结点对象是大型继承链的一部分。它充满了我需要在上传之前删除的样板业务逻辑代码,但是在根目录中是 javax.websocket.Endpont 类,在该类中,我们仅实现了 onOpen(Session会话,EndpointConfig配置)方法。调试时我没有使用该方法,似乎早就失败了...

1 个答案:

答案 0 :(得分:1)

您的请求标头看起来像这样...

Accept: application/json, application/*+json
Accept-Encoding: gzip
Cache-Control: no-cache
Connection: keep-alive
Content-Type: application/json
Host: 127.0.0.1:8080
Pragma: no-cache
Sec-WebSocket-Key: sMQPm6Cf00itLII3QBb4w==
Sec-WebSocket-Version: 13
Upgrade: websocket
User-Agent: Java/1.8.0_144

那是无效的WebSocket升级请求。 最明显的遗漏是

Connection: upgrade

但是还有其他字段,兼容的WebSocket客户端永远不会设置。

Content-Type: application/json
Accept: application/json, application/*+json
Accept-Encoding: gzip