Websockets 未在代理后面连接

Websockets not connected behind proxy

这是一个很常见的问题,但我找不到针对我的具体情况的解决方案。我使用的是 Glassfish 4.1.1,我的应用程序实现了 Websockets。

在客户端,我只需通过以下方式连接到 WS-server:

var serviceLocation = "ws://" + window.location.host + window.location.pathname + "dialog/";
var wsocket = new WebSocket(serviceLocation + token_var);

在服务器端,websockets 是通过@ServerEndpoint 功能实现的,看起来很常见:

@ServerEndpoint(value = "/dialog/{token}", decoders = DialogMessageDecoder.class)
public class DialogWebsoketEndpoint {

    @OnOpen
    public void open(final Session session, @PathParam("token") final String token) { ... }
etc.
}

直到客户尝试在代理后面连接时一切正常。 使用此测试:http://websocketstest.com/ 我发现客户的计算机在 http-proxy 1.1 之后工作。 他无法连接到 websockets,onopen 根本不触发。 wsoscket.readyState永远不会变成1。

如何调整我的 ServerEndpoint 以使此代码即使在客户通过代理连接时也能正常工作?

提前致谢!

更新:我会在该计算机上提供 websocketstest 的屏幕截图:

在我的电脑上,除了一件事外似乎很相似: HTTP 代理:NO.

正如对问题的评论所述,Proxy 似乎没有正确支持 Websockets。

这是一个常见问题(一些 cell-phone 公司的代理会破坏 websocket 连接),解决方案是使用 TLS/SSL 连接。

出现这个问题主要是因为一些代理 "correct"(读取:损坏)Websocket 请求 headers.

但是,当使用 TLS/SSL 时,代理无法读取 header 数据(已加密),导致大多数代理上的数据 "pass-through"。

这意味着 headers 将安全到达另一端并且代理将(大部分)忽略连接...这可能仍然会导致连接超时问题,但它通常会解决问题。

编辑

请注意,浏览器将保护客户端不会将 non-encrypted 内容与加密内容混合在一起。确保脚本在使用 TLS/SSL 连接时使用 wss 变体启动 ws 连接。