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

时间:2018-01-16 09:15:24

标签: node.js amazon-web-services sockets nginx

我想要实现的目标是什么?

在我的ec2实例上设置socket.io,使用Nginx作为Web服务器,使用AWS Application Load Balancer,使用Route53解析DNS以指向我的应用程序负载均衡器。

以下是我在网上找到的解决方案列表:

  1. 在应用程序级别使用网络负载均衡器代替TCP 80,TCP 443和SSL。客户端套接字连接网址为https://mydomain:9000,我不断收到错误websocket connection closed before connection could be established.。目标群体已启用粘性。

  2. 使用应用程序负载均衡器,并将基于路径的规则添加到我的侦听器中以获取路径/socket.io,并将其转发到启用了粘性的其他目标组:现在我尝试了443协议和使用HTTPS协议的9000端口。我得到了同样的结果。

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

  4. 这是我的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))
    }
    

    更新:我犯了一个愚蠢的错误,虽然这没有解决我的问题,但是因为socket.io和我的nodejs服务器正在侦听,所以客户端连接URL将是https://mydomain在同一个港口。我现在正在使用Application Load Balancer,我收到了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"
    

1 个答案:

答案 0 :(得分: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`);
});