Socket.io + Nginx + AWS Application Load Balancer 连接在建立之前被关闭

5

我想要实现什么?

在我的EC2实例上设置socket.io,使用Nginx作为Web服务器,使用AWS应用负载均衡器和Route53将DNS解析到我的应用程序负载均衡器。

下面是我在网上找到并尝试过的解决方案:

  1. 使用网络负载均衡器并在应用层使用TCP 80、TCP 443和SSL。客户端Socket连接URL将为https://mydomain:9000,但我一直收到错误消息websocket connection closed before connection could be established。目标组启用了黏性会话。

  2. 使用应用程序负载均衡器,在侦听器中添加基于路径的规则,将路径/socket.io转发到启用了黏性会话的不同目标组:我尝试了HTTPS协议下的443端口和9000端口,但结果相同。

  3. 使用我的负载均衡器的公共DNS作为套接字客户端连接的URL。但结果仍然相同。

这是我的Nginx配置文件:

    # SSL configuration

     listen 443 ssl default_server;
     listen [::]:443 ssl default_server;

    ssl_certificate  /path/to/ssl.crt;
    ssl_certificate_key /path/to/private_key.pem;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    if ($ssl_protocol = "") {
  rewrite ^   https://$server_name$request_uri? permanent;
}

    server_name _;

    location / {
            # First attempt to serve request as file, then
            # as directory, then fall back to displaying a 404.
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_http_version 1.1;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-NginX-Proxy true;
    proxy_pass http://localhost:9000;

    }

现在,我应该让您知道,我已经强制使用websocket传输协议来使用套接字客户端,因为xhr-polling会给我以下错误,而我又不知道该怎么处理。

Failed to load https://my_domain/socket.io/?EIO=3&transport=polling&t=M3lhVWi: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://localhost:4444' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

如果有人能帮我建立套接字连接的任何一种情况,那我会非常感激。另外,如果您需要其他相关信息,请询问。编辑 这是我设置socket.io的方法。
const app = express();

const server = http.createServer(app);

const socketio = io(server, {
    serveClient: false,
    pingInterval: 10000,
    pingTimeout: 5000,
    cookie: false,
    transport: ['websocket', 'xhr-polling']
});

socketConfig(socketio);

//and here's socketConfig

export function socketConfig(socketio) {
    let localSockets = [];
    socketio.on('connection', connectConfig(socketio, localSockets))
}

更新:我的一个愚蠢错误,虽然这没有解决我的问题,但客户端连接 URL 应该是 https://mydomain 因为 Socket.io 和我的 Node.js 服务器正在监听同一端口。现在我正在使用应用程序负载均衡器,并且遇到了 502 错误。
更新:我检查了我的 Nginx 错误日志并发现了以下内容:
upstream prematurely closed connection while reading response header from upstream, client: 172.31.11.251, server: _, request: "GET /socket.io/?EIO=3&transport=websocket HTTP/1.1", upstream: "http://127.0.0.1:9000/socket.io/?EIO=3&transport=websocket", host: "mydomain"

我曾经遇到过类似的问题。我们在客户端连接时将 https://ourdomain 替换为 wss://ourdomain:io.connect('wss://ourdomain', {path:'<your_application_route_if_you_have_any>/socket.io' }) - Dhaval Chaudhary
但是 socket.io 会自动处理这个问题,不过它没有起作用。 - relentless-coder
如果您能分享您的服务器配置,那么我就可以尝试一下。 - Dhaval Chaudhary
@DhavalChaudhary 请检查编辑,我已经更新了所需的细节。 - relentless-coder
1个回答

0

好的,我已经修复了,这是我自己非常愚蠢的错误:

我的代码中有这个:

app.listen(config.port, config.ip, () => {
    console.log(`express server listening on port ${config.port} in ${config.env} mode`);
});

改为:

server.listen(config.port, config.ip, () => {
    console.log(`express server listening on port ${config.port} in ${config.env} mode`);
});

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