0

WebSocket connection to 'wss://myapp.com/socket.io/?EIO=4&transport=websocket&sid=9NkQ7PBU8Mjvmp0_AAAD' failed: WebSocket is closed before the connection is established.

I can't seem to figure this out...try almost everything, would be awesome if someone can help me out here. Ig

react code = on port 3000

const ENDPOINT = "https://myapp.com/socket.io/";
const socket = io(ENDPOINT, {
 withCredentials: true,
 extraHeaders: {
 "my-custom-header": "abcd"
}

node.js code = apps on port 8080, socket.io on port 8081

const server = http.createServer(app);
const io = socketIo(server, {
  cors: {
    origin: "https://www.myapp.com:3000",
    methods: ["GET", "POST"],
    allowedHeaders: ["my-custom-header"],
    credentials: true
  }});
server.listen(8081, () => console.log(`Listening on port 8081`));

nginx code = ubuntu@ip-10-0-0-000:/etc/nginx/sites-enabled/myapp.com

server_name www.myapp.com myapp.com;
        location / {
        root /home/ubuntu/myapp/myapp_frontend/build/;
        try_files $uri /index.html;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        }
        location /api/ {
        proxy_pass http://127.0.0.1:8080;
        }
        location /socket.io/ {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        }
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/myapp.com-0001/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/davidcodedesign.com-0001/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
    if ($host = www.myapp.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    if ($host = myapp.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
listen 80;
server_name www.myapp.com myapp.com;
    return 404; # managed by Certbot
Jose Lora
  • 1,392
  • 4
  • 12
  • 18
David L
  • 3
  • 2

1 Answers1

0

so I'm guessing that you have already figured this out but there were a lot of MERN stack / nginx /socket.io queries going unanswered so I'll just offer what got working for me for the future.

Three points for me were going wrong and I was fixing one of them and trying something else and only stumbled onto the right combination of all 3.

  1. React Front end. I set my socket as context.
import React, { useEffect, useState } from "react";
import { io } from "socket.io-client";

export const SocketContext = React.createContext();

export function SocketProvider({ children }) {
  const [socket, setSocket] = useState();

  useEffect(() => {
    const newSocket = io("http://<mysubdomain>.<mydomainname>.ie", {
      path: "/socket.io/",
    });
    setSocket(newSocket);
    console.log("new socket", newSocket);
    return () => newSocket.close();
  }, []);

  return (
    <SocketContext.Provider value={socket}>{children}</SocketContext.Provider>
  );
}

for const newSocket = io(...) having the /socket.io/ in the path option made a difference as well as having it surrounded by "/" marks.

In my node.js server simply have it running on port 8800.

const io = new Server(8800, {cors: { origin: ["http://<mysubdomain>.<mydomainname>.ie"] } });

In my config I have my frontend and backend running on the same domain so cors might not be necessary, but cors is something to consider in your debugging but it was not my issue.

For my nginx config I used this set-up in /etc/nginx/sites-available/

server {
 listen 80;
 server_name <subdomain>.<domainname>.ie;

location / {
 root /var/www/chess;
 index  index.html index.htm;
 proxy_http_version 1.1;
 proxy_set_header Upgrade $http_upgrade;
 proxy_set_header Connection 'upgrade';
 proxy_set_header Host $host;
 proxy_cache_bypass $http_upgrade;
 try_files $uri $uri/ /index.html;
     }
location /socket.io/ {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For 
      $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_set_header X-NginX-Proxy false;

      proxy_pass http://<subdomain>.<domainname>.ie:8800;
      proxy_redirect off;

      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }
}

So I went through the docs - particularly the troubleshooting section and found it fairly useful https://socket.io/docs/v4/troubleshooting-connection-issues/

However the example proxy settings that were provided there came up with the same error as yours and so I grabbed another config with additional directives from Socket.io with nginx however the location did not work for me so I simply grabbed just the directives and popped it into my location.

Something to note - I haven't carried out SSL yet so double check http vs https on all of these three points.

https://www.youtube.com/watch?v=lZVAI3PqgHc&t=872s This video from nginx also helped get a higher level understanding of proxy_pass.

Check versions of socket and make sure they are the same and up to date.

This worked for me after two days of banging my head against a wall so I hope it helps you

JoshD
  • 36
  • 5