WebSocket 连接失败:WebSocket 打开握手被取消

WebSocket connection failed: WebSocket opening handshake was canceled

我最近设置了一个 EC2 实例(在没有负载均衡器的 VPC 中),诚然配置有点奇怪,但这是我们 运行ning 的 Web 应用程序所需要的。

Web 服务器(在 Haskell 中)运行正在端口 4433 上(标准端口为 Apache 实例保留)并且正在接收从另一个系统广播的 UDP 数据包。我有许多端口完全开放(仅在测试期间),如下所示(来自安全组):

Custom TCP Rule    4433     tcp 0.0.0.0/0   ✔
Custom TCP Rule    8080     tcp 0.0.0.0/0   ✔
SSH                22       tcp 0.0.0.0/0   ✔
HTTP               80       tcp 0.0.0.0/0   ✔
HTTPS              443      tcp 0.0.0.0/0   ✔
Custom UDP Rule    30090    udp 0.0.0.0/0   ✔
Custom UDP Rule    30089    udp 0.0.0.0/0   ✔

TCP 套接字的 JavaScript 请求在同一端口上设置套接字(使用分配给 AWS 的 public IP 的 URL),这就是请求 returns 错误:

WebSocket connection to 'wss://[URL]:4433/projects/socket' failed: WebSocket opening handshake was canceled.

将套接字绑定到 0.0.0.0 会导致同样的错误。

为了启动 Haskell 网络服务器,我必须引用 AWS 提供的 内部 IP,因为它不会 运行 在引用 public 弹性IP服务提供的IP。认为这就是问题所在,我将套接字请求更改为此...

wss://[internal ip]:4433/projects/socket

这改变了错误:

WebSocket connection to 'wss://[internal IP]:4433/projects/socket' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED

这个错误对我来说很有意义,因为外部世界无法使用内部 IP。

我在 AWS 上的 websockets 上阅读的所有内容都涉及 ELB(弹性负载均衡器),我不需要其中之一。我已经尝试了所有当前发布的答案中的所有内容(有些问题甚至没有得到答案),但都无济于事。我还与亚马逊建立了一个支持案例(将近 24 小时前),但尚未收到回复。

附加信息

导航到 http://[URL]:4433/projects/socket 会产生 'WebSocket Available',其中 URL 是我们希望使用的那个以及 AWS 提供的 Public DNS。

运行 netstat -plunt 显示以下内容:

tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp        0      0 [internal IP]:8080      0.0.0.0:*               LISTEN      -
tcp        0      0 [internal IP]:4433      0.0.0.0:*               LISTEN      -
tcp6       0      0 :::22                   :::*                    LISTEN      -
tcp6       0      0 :::443                  :::*                    LISTEN      -
tcp6       0      0 :::80                   :::*                    LISTEN      -
udp        0      0 [internal IP]:30089     0.0.0.0:*                           -
udp        0      0 0.0.0.0:30090           0.0.0.0:*                           -
udp        0      0 0.0.0.0:11950           0.0.0.0:*                           -
udp        0      0 0.0.0.0:68              0.0.0.0:*                           -
udp6       0      0 :::38450                :::*                                -

有人在 AWS 上遇到过类似的 websockets 问题吗?如果有,您是如何解决问题的?

Haskell 服务器和 Apache 服务器之间的 SSL 证书不匹配。

必须使用有关实例新证书的信息重建 Haskell 服务器。更复杂的是,正确的 SSL 库 (libssl0.9.8 libssl-dev) 没有安装在 EC2 实例上,这导致我在 Haskell 服务器重建期间出现问题。知道 EC2 实例是 "blank canvas" 使得缺少该安装是我的错。

一旦我安装了 libssl,我就能够重建 Haskell 服务器,它指向新的证书。一旦证书 "matched" websocket 问题就消失了。

重申一下,我们的情况很独特。我们有一个 Apache 服务器(端口 80 和 443)和一个 Haskell 服务器(端口 8080 和 4433),它们相互通信,通过 websockets 执行发布-订阅操作。两个服务器之间的证书不匹配(不管是什么类型,它可能是多个 Apache 实例)导致了 SSL 警告。来自 SSL 的任何警告都会破坏任何建立或维护 websocket 的尝试(因此握手已取消消息)。

Another Whosebug post 提供了一些线索,在这个过程中提供了巨大的帮助。更具体地说,这个警告 -

The key to the problem is this: If your SSL certificate causes a warning of any sort, wss:// WebSocket connections will immediately fail, and there is no canonical way to detect this.

我 运行 在从 file:// URL 使用基于 blob 的网络工作者的 websockets 时遇到此错误。我怀疑网络服务器中的 运行 可能会解决这个问题;我在调试时通过关闭 SSL 解决了这个问题。

如果 websocket url 未正确放入 frontend

中,则会出现此错误

检查这个答案

放置前端 url 的正确方法是 "wss://example.com/wss/"

放置前端的错误方式 url 是

wss://example.com:8080/wss/ -> port no should not be mentioned
ws://example.com/wss/ -> url should start with wss only.
wss://example.com/wss -> url should end with / -> most important