I'm having trouble deploying my app. The app itself works just fine, but websockets fail to connect:
WebSocket connection to 'wss://localhost:8080/socket.io/?combat_id=elayn-1670267089069&EIO=4&transport=websocket' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
On localhost everything worked fine, even on Heroku. The deployment server I use now has nginx (running on port 8000) and I probably have something wrong regarding either nginx config or some wrong IP address somewhere.
My nginx configuration file (nginx version 1.18.0):
server {
listen 0.0.0.0:8000;
listen [::]:8000;
root /app/app/static/build;
index index.html;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_redirect default;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
}
location /socket.io/ {
proxy_pass http://127.0.0.1:8080/socket.io;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect default;
proxy_set_header Host $host;
}
}
My app.py:
from app import app, socketio
if __name__ == "__main__":
socketio.run(app, debug=False, port="8080")
My __init**__**.py:
import os
from dotenv import load_dotenv
from flask import Flask, render_template, redirect, url_for, flash, request, abort
from flask_bootstrap import Bootstrap
from werkzeug.security import generate_password_hash, check_password_hash
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm import relationship
from flask_login import UserMixin, login_user, LoginManager, login_required, current_user, \
logout_user
from flask_cors import CORS
from flask_socketio import SocketIO, emit
# -------------------- INIT APP --------------------
load_dotenv()
app = Flask(__name__, template_folder="./")
app.debug = True
app.config["SECRET_KEY"] = os.environ.get("SECRET_KEY")
app.config['CORS_HEADERS'] = 'Content-Type'
socketio = SocketIO(app, cors_allowed_origins="http://127.0.0.1:8080/", logger=True, engineio_logger=True)
# CONNECT TO DB
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get("DATABASE_URL")
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# LOGIN MANAGER
db = SQLAlchemy(app)
login_manager = LoginManager(app)
bootstrap = Bootstrap(app)
from app import models, forms, routes, handlers
from app.auth import forms, routes
# db.create_all()
# db.session.commit()
This is the startup line of code:
/srv/venv/bin/gunicorn -b 127.0.0.1:8080 --worker-class eventlet -w 1 app:app
Socket.io in React:
socket = io("localhost:8080/", {
transports: ["websocket"],
cors: {
origin: "*",
},
query: `combat_id=${combatInfo.id}`,
});
What I tried so far: change all the IP addresses (in React too) to either localhost:8080 or 127.0.0.1:8080 or http://127.0.0.1:8080, tried to remove the port in socket.io url too, tried to add/remove some nginx configurations based on what I found while googling. Also tried gevent instead of eventlet. Nothing has worked for me so far.
The problem really was in the nginx configuration, not in my app. Missing proxy_read_timeout 86400 was the main cause. My final (and working) configuration looks like this:
server {
listen 0.0.0.0:8000;
listen [::]:8000;
server_name domain.name;
root /app/app/static/build;
index index.html;
location / {
proxy_pass http://localhost:8080;
proxy_redirect http://localhoat:8000 https://domain.name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
}