WebSocket 连接失败:WebSocket 打开握手被取消 [英] WebSocket connection failed: WebSocket opening handshake was canceled

查看:70
本文介绍了WebSocket 连接失败:WebSocket 打开握手被取消的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have recently setup an EC2 instance (in a VPC with no load balancer) and admittedly the configuration is a bit odd, but it is what is required for the web application we're running.

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

The web server (in Haskell) is running on port 4433 (standard ports are reserved for an Apache instance) and is receiving UDP packets being broadcast from another system. I have many of the ports wide-open (just during testing) as shown here (from Security Groups):

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 公共 IP 的 URL),这是请求返回错误的地方:

The JavaScript for the TCP socket makes a request to setup the socket on this same port (using the URL assigned to the AWS's public IP) and this is where the request returns the error:

WebSocket 连接到wss://[URL]:4433/projects/socket"失败:WebSocket 打开握手被取消.

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

将套接字绑定到 0.0.0.0 会导致相同的错误.

Binding the socket to 0.0.0.0 results in the same error.

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

In order to start the Haskell web server I had to reference the internal IP provided by AWS as it would not run when referencing the public IP provided by the elastic IP service. Thinking this is where the problem came in I changed my socket request to this...

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

这改变了错误:

WebSocket 连接到 'wss://[internal IP]:4433/projects/socket' 失败:连接建立错误:net::ERR_CONNECTION_REFUSED

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

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

That error makes sense to me as the internal IP is not available to the outside world.

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

Everything that I've read on websockets on AWS involves an ELB (Elastic Load Balancer) and I am not in need of one of those. I have tried all of the things in all of the currently posted answers (some of the questions haven't even gotten answers) on SO to no avail. I also setup a support case with Amazon (nearly 24 hours ago) which hasn't received a response.

导航到 http://[URL]:4433/projects/socket 会产生WebSocket Available",其中 URL 是我们希望使用的 URL 以及 AWS 提供的公共 DNS.

Navigating to http://[URL]:4433/projects/socket yields 'WebSocket Available' where the URL is the one we wish to use as well as the Public DNS provided by AWS.

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

Running netstat -plunt reveals the following:

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 问题吗?如果是这样,您是如何解决问题的?

Has anyone had a similar problem with websockets on AWS? If so, how did you solve the problem?

推荐答案

Haskell 服务器和 Apache 服务器之间存在 SSL 证书不匹配.

There was an SSL certificate mismatch between the Haskell server and the Apache server.

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

The Haskell server had to be rebuilt with information concerning the new certificates for the instance. Further complicating this the proper SSL library (libssl0.9.8 libssl-dev) was not installed on the EC2 instance which was causing me problems during the rebuild of the Haskell server. Knowing an EC2 instance is a "blank canvas" makes the lack of that installation my fault.

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

Once I had the libssl installed I was able to rebuild the Haskell server with it pointing to the new certificates. Once the certificates "matched" the websocket issue disappeared.

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

Just to reiterate, ours is a unique situation. We have an Apache server (ports 80 and 443) and a Haskell server (ports 8080 and 4433) which communicate with each other, performing a pub-sub operation over websockets. A certificate mismatch between the two servers (it would not have mattered what type, it could have been multiple Apache instances) caused an SSL warning. Any warning from SSL will tear-down any attempt to establish or maintain a websocket (hence the handshake canceled message).

另一个 StackOverflow 帖子 提供了一些在这个过程中非常有帮助的线索.更具体地说,这个警告 -

Another StackOverflow post provided some clues that were of tremendous help during this process. More specifically this warning -

问题的关键在于:如果您的 SSL 证书导致任何形式的警告,wss://WebSocket 连接将立即失败,并且没有规范的方法来检测这一点.

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.

这篇关于WebSocket 连接失败:WebSocket 打开握手被取消的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆