Socket.io + Nginx + AWS Application Load Balancer connection closed before it can be established

rel*_*der 5 sockets nginx amazon-web-services node.js

What I am trying to achieve?

To setup socket.io on my ec2 instances, with Nginx as the web server, with an AWS Application Load Balancer, and Route53 that resolves the DNS to point to my Application Load Balancer.

Here are the list of solutions that I found online that I have tried:

  1. Use Network load balancer instead with TCP 80, and TCP 443, and SSL at the application level. The client socket connect url would be https://mydomain:9000 and I keep getting error websocket connection closed before connection could be established.. The target group has stickiness enabled.

  2. Use Application Load Balancer, and add a path based rule to my listener for path /socket.io and forward it to a different target group with stickiness enabled: Now I tried both 443 protocol and 9000 port with HTTPS protocol. I got same result.

  3. Use the public DNS of my load balancer as the url for the socket client connection. And still same result.

Here's my nginx config file:

    # 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;

    }
Run Code Online (Sandbox Code Playgroud)

Now, I should let you know that I have forced socket client to use websocket transport, xhr-polling was giving me the following error, which again I have no idea what to do with it.

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.
Run Code Online (Sandbox Code Playgroud)

If someone can help me with either of the situation that would establish a socket connection, then I'd be really thankful. Also, please ask if you need any other relevant information.

Edit Here's how I setup my 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))
}
Run Code Online (Sandbox Code Playgroud)

Update: A stupid mistake on my part, although this didn't solve my problem, the client connection url would be https://mydomain since the socket.io and my nodejs server are listening on the same port. I am using Application Load Balancer now, and I am getting 502 error.

Update: I checked my Nginx error logs and found this:

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"
Run Code Online (Sandbox Code Playgroud)

rel*_*der 0

好吧,我修复了它,这对我来说是一个非常愚蠢的错误:

我的代码中有这个:

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

代替:

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