我正在玩Jetty( 9.2.3v20140905 ),当我遇到Jetty的代码时,我尝试使用自己的ServerEndpointConfig
来连接网络套接字端点看看它是如何使用的。
我注意到在创建Web套接字对象时在JsrCreator
中使用它:
Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp){
...
// modify handshake
configurator.modifyHandshake(config,hsreq,hsresp);
...
}
我读了modifyHandshake
ServerEndpointConfig
( javax.websocket-api 1.0 )的javadoc,声明:
在容器响应之后由容器调用 一个结构良好的握手请求。容器已经存在 检查此配置有匹配的URI ,确定了 使用 checkOrigin方法进行原点的有效性,并填写 基于此配置的协商子协议和扩展。 自定义配置可能会覆盖此方法以进行检查 请求参数并修改服务器已制定的握手响应。 和URI检查也。 如果开发人员没有覆盖此方法,则不再进一步 请求和响应的修改由实现进行。
以下是Jetty所做的事情:
Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp){
...
// modify handshake
configurator.modifyHandshake(config,hsreq,hsresp);
// check origin
if (!configurator.checkOrigin(req.getOrigin())){...}
...
resp.setAcceptedSubProtocol(subprotocol);
...
resp.setExtensions(configs);
}
如您所见,在调用配置器之后检查原点。在调用配置器>>后,响应被修改。
acceptWebSocket
的{{1}}方法调用了WebSocketCreator:
WebSocketServerFactory
然后打电话:
Object websocketPojo = creator.createWebSocket(sockreq, sockresp);
也会通过private boolean upgrade(HttpConnection http, ServletUpgradeRequest request, ServletUpgradeResponse response, EventDriver driver)
修改回复:
HandshakeRFC6455
所以我无法仅使用我的配置器修改响应,因为Jetty无论如何都会改变它。
在我看来,Jetty不符合JSS 356,WebSocket的Java API,是吗?
答案 0 :(得分:0)
啊,这是JSR-356规范中许多含糊不清和定义不明确的部分之一。
您可能需要阅读open bugs against the spec。
如果原始的1.x规范完全遵循,有许多现实世界的场景示例无法实现。
现在,要解决问题的具体细节:
为什么在Jetty实现中的modifyHandshake之后调用checkOrigin?
这是因为有一些有效的场景(特别是CDI和Spring),最终用户checkOrigin
实现所需的信息无效或存在,直到调用modifyHandshake
调用
基本上,创建端点Configurator
,调用modifyHandshake
,此时,所有库集成(CDI,Spring等)都会启动,即端点进入时WebSocket(RFC6455)CONNECTING状态。 (一旦调用端点的onOpen,则WebSocket RFC6455状态进入OPEN状态)
正如您可能已经注意到的那样,当涉及CDI(或Spring)时,对象的范围和生命周期的规范中没有定义。
1.x JSR356规范实际上与servlet容器特定行为保持距离,这样做是为了使规范尽可能通用,并且能够拥有非servlet websocket服务器容器。不幸的是,这也意味着servlet容器中有许多用例没有与1.x JSR356规范相匹配。
更新JSR356规范以在WebSocket上正确定义CDI范围后,可以修复checkOrigin
之后modifyHandshake
的这个怪癖。
为什么在modifyHandshake后修改响应的实现?
实现必须修改响应,否则响应对于HTTP / 1.1升级无效,实现需要与端点及其配置合作,子协议和扩展使这成为现实。 (请注意,JSR356规范在Extensions上播放?)
这也是一个承诺在下一个JSR356版本中得到纠正的领域。
目前关于WebSocket over HTTP / 2规范的工作使得这更加有趣,因为它(当前)没有使用HTTP / 1.1升级语义。它只是在握手时出现(没有升级,没有原点等)。