AWS EC2 实例无法处理 WebSocket Http 升级请求

AWS EC2 instance unable to handle WebSocket Http Upgrade request

配置:

当我在本地网络上托管时,我能够连接到每台可以使用 WebSockets 的设备(包括我的 phone)。但是,当在 AWS 上发送 HTTP 升级请求的任何客户端都会收到此错误:

WebSocket connection to 'ws://###.com:8080/###/chat' failed: Connection closed before receiving a handshake response

Firefox can’t establish a connection to the server at 'ws://###.com:8080/###/chat'

但是,它适用于 Google Chrome。我相信这是因为至少根据 Wireshark 显示的内容,它没有发送升级 HTTP 请求。

如果有人能告诉我配置错误的地方,非常感谢。

编辑: 我已经添加了一个 NGINX 反向代理来获取一些日志

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}
upstream websocket {
    server 127.0.0.1:7676;
}
server {
    listen 8080 ssl;
    location / {
    proxy_pass https://websocket;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
}
    add_header Strict-Transport-Security "max-age=31536000";
    ssl on;
    ssl_certificate /home/ubuntu/ssl/cert.crt;
    ssl_certificate_key /home/ubuntu/ssl_cert.key;
    ssl_prefer_server_ciphers on;
}

Google Chrome 仍然有效: "GET /###/chat HTTP/1.1" 101

所有其他不起作用的东西给出: "GET /###/chat HTTP/1.1" 400

我从 ws:// 更改为 wss://,现在一切正常。我认为 Chrome 可能一直在后台更改与 wss:// 的连接。

##短版##

我不太了解 NGINX 配置,但我看到已请求 SSL,并且您的 SSL 证书似乎有效(重要!)。 The connection point rule can be summarized as:

  • wsshttps
  • 上连接
  • wshttp
  • 上连接

反之亦然:

  • https 只接受 wss
  • http 接受 ws。我认为它也接受 *wss 但你会收到警告或错误

##正式回答##

websocket的宝典是RFC 6455。在第 4.1.5 节中:

If /secure/ is true, the client MUST perform a TLS handshake over the connection after opening the connection and before sending the handshake data [RFC2818]. If this fails (e.g., the server's certificate could not be verified), then the client MUST Fail the WebSocket Connection and abort the connection. Otherwise, all further communication on this channel MUST run through the encrypted tunnel [RFC5246].

secure 标志由 URI 定义。第 3 节定义什么是 secure

The URI is called "secure" (and it is said that "the secure flag is set") if the scheme component matches "wss" case-insensitively.

TL;DR

  • 您开启了 SSL
  • 您的连接点被重定向到 https://
  • 你需要wss://否则握手会失败