amazon-web-servicesamazon-ec2flask-socketio

Flask socket-io 404 error upon polling ec2


So I have been dealing with this for the past couple of days and still didn't come up with a solution yet. I have been spending sometime over github or stackoverflow and tryout the approach mentioned but still not working like:

Before driving into the question, let me simply explain my current project.

Project: FrontEnd is reactjs where backend is Flask where the backend got deployed by gunicorn with the nginx web server.

AWS Architecture: Route53 -> Cloudfront -> (S3, EC2). S3 buckets serves the frontend (react build) and EC2 serves the backend (API, websocket). I have got my own domain name and certificated by the ACM and put in at the CloudFront. I put both the S3 and EC2 (2 origins) inside the cloudfront where the S3 serves web hosting loaded over HTTPS and send request to the EC2. So the connection between cloudfront and ec2 is by through the HTTP.

Behaviour for the S3 is Default(*) and EC2 is (/api). The method is set to GET/POST/PUT... which i enable all for the request. When it comes to the api request part, everything works perfectly fine, the request is being handled properly and send response back to the client-side. The problem occurs only for the websocket where i got this error:

GET https://www.jungp.online/socket.io/?user_id=1&EIO=4&transport=polling&t=OtLZxOo 404 (Not Found)

Frontend react for connecting to io

  useEffect(() => {
      const socket = io("https://www.jungp.online", {
      path: '/socket.io',
      query: {
        user_id: Cookies.get("userId")
      }
    });

EC2 security group: enter image description here

Nginx configurations:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    listen 80;
    server_name www.jungp.online;

    location / {
        proxy_pass http://127.0.0.1:8080;
        include /etc/nginx/proxy_params;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }

    location /socket.io {
        proxy_pass http://127.0.0.1:8080/socket.io;
        include /etc/nginx/proxy_params;
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Command to run:

gunicorn -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -b 0.0.0.0:8080 wsgi:app

app.py

app = Flask(__name__)
socketio = SocketIO(app, path='/socket.io', cors_allowed_origins="*")
CORS(app)

wsgi.py:

from app import socketio, app
if __name__ == "__main__":
    socketio.run(app, host="0.0.0.0", port=8080)

Any help is highly appreciated, thanks in advance.


Solution

  • Ok, so after dealing with this for the couple of days, I finally able to figure out the solution.

    The solution is fairly simple, since I got my ec2 and s3 behind the CloudFront, the ec2's behavior must be configured to take the routing path for socket.io. So just simply add the path pattern /socket.io/* to the behavior does the trick.

    Hopefully this will help other that has the same architecture as mine and facing the same problem.