亚马逊 EC2 上的 Websockets 连接失败

13

我有一个在Netty服务器上运行Atmosphere框架的实时通知系统,使用Websockets协议。

该系统在我的本地机器上可以完美运行,但是当我在EC2上部署它时,它似乎无法正常工作。虽然我能够使用telnet连接到远程Netty服务器,但浏览器(Firefox)抛出以下错误:

Using URL: ws://beta.myapp.com:2880/myhandle?id=1&name=Chinese_food_rule_2&    X-Atmosphere-tracking-id=35490c47-59d6-abf6-36fa-431aa340d90a&X-Atmosphere-Framework=0.9&X-Atmosphere-Transport=websocket&X-Cache-Date=0&Content-Type=application/json

Websocket error, reason: undefined

Firefox can't establish a connection to the server at ws://beta.myapp.com:2880/myhandle?id=1&name=Chinese_food_rule_2&X-Atmosphere-tracking-id=35490c47-59d6-abf6-36fa-431aa340d90a&X-Atmosphere-Framework=0.9&X-Atmosphere-Transport=websocket&X-Cache-Date=0&Content-Type=application/json.

Websocket closed, reason: Connection was closed abnormally (that is, with no close frame being sent).

服务器甚至没有收到请求,这让我想到可能是某些我不知道的 EC2 web sockets 陷阱。


2
您的防火墙设置是否已开放2880端口? - Veebs
6个回答

10

我在php中遇到了同样的问题。

解决方法是:使用你的EC2的私人IP地址创建websocket,然后使用EC2的公共IP地址或URL与websocket端口连接。

这样你就可以从EC2 web socket获得响应了。


1
如何处理?我正在使用 Python + Tornado。它在本地机器上运行良好,但在 EC2 Ubuntu 上不行。 - Dustin Sun
感谢@ABIRAMAN。是的,在您的EC2中使用WebSocket连接,请使用“公共IP”而不是私有IP。 - Amit Thawait
将尝试回答点击此处发布的问题。 - Nɪsʜᴀɴᴛʜ ॐ
这个答案在过去几年中已经两次拯救了我这个蠢货的后半生。 - zanderwar

8

你是否在使用负载均衡器(ELB)?如果是,你需要切换到TPC而不是HTTP,因为Websockets不支持HTTP层。当运行TCP时,你将失去粘性和检索客户端IP的可能性,但Websockets将一直工作。 =)

关于EC2/ELB/Websockets的更多信息:
http://johan.firebase.co/post/31047804966/the-state-of-websockets-ssl-and-sticky-sessions-in
http://johan.heapsource.com/post/31047804966/the-state-of-websockets-ssl-and-sticky-sessions-in https://web.archive.org/web/20160328183724/http://johan.heapsource.com/post/31047804966/the-state-of-websockets-ssl-and-sticky-sessions


2
http://johan.heapsource.com/post/31047804966/the-state-of-websockets-ssl-and-sticky-sessions-in - bendytree
所有链接现在都已失效 :( - Ron
整个域名似乎已经离线,但这里有一个 wayback 链接: https://web.archive.org/web/20160328183724/http://johan.heapsource.com/post/31047804966/the-state-of-websockets-ssl-and-sticky-sessions不过这些信息已经非常过时了,我不知道它们还能帮多少忙。 - moodh

3

@ABIRAMAN帮我接近了答案。

我一直在使用localhost连接websocket(HapiJS/NES),如下所示:

const client = new Nes.Client('ws://localhost:3000')

更改为以下公共AWS IP,它可以工作:

const client = new Nes.Client('ws://5.5.5.5:3000')

请注意,我还在Amazon的EC2控制面板中允许了127.0.0.1和0.0.0.0/0上的3000端口。另外,5.5.5.5不是Amazon给我的IP ;)


0

0

我是来自2023年的人。@abiraman的回答帮了我很多。

其次,wscat 是一个非常好用的调试websocket连接的工具。

我的情况:

  • AWS Ec2服务器启用了websocket。
  • 尝试从DEV LAPTOP应用程序连接到它-无法连接(ECONNREFUSED错误)
  • 尝试从SERVER命令行本身使用wscat -c ws://ADDRESS:PORT连接
    • 公共IP地址失败
    • 私有地址失败
    • localhost127.0.0.1通过(在服务器上)

在阅读Abirahman的答案后,我尝试停止并重新启动我的私有IP上的websocket服务-成功了!

现在问题是 - 我相当确定这个设置(ws127.0.0.1上)以前是正常工作的,突然就不工作了... 这是AWS的怪癖吗?这是一个不稳定的解决方案,可能会再次出问题吗?请在评论中分享任何经验- 谢谢。

-1
使用nc命令(linux / OSX命令行)可以轻松检查端口是否正常运行。
nc -z www.google.com 80

如果不行的话,请检查您的安全组。登录EC2:
在网络和安全下面: 选择安全组-> 打开默认安全组-> 入站规则。您可以在那里创建新规则。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接