You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

部署Flask+Nginx+Gunicorn+React应用时WebSocket连接失败求助

WebSocket连接失败:ERR_CONNECTION_REFUSED

问题描述

应用本身运行正常,但WebSocket无法建立连接,报错信息:

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

应用在本地及Heroku部署均正常,当前服务器使用Nginx 1.18.0监听8000端口,怀疑问题出在Nginx配置或IP地址设置上。

现有配置与代码

Nginx配置文件

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

Flask后端代码

app.py

from app import app, socketio

if __name__ == "__main__":
    socketio.run(app, debug=False, port="8080")

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()

应用启动命令

/srv/venv/bin/gunicorn -b 127.0.0.1:8080 --worker-class eventlet -w 1 app:app

React前端Socket.io代码

socket = io("localhost:8080/", {
    transports: ["websocket"],
    cors: {
        origin: "*",
    },
    query: `combat_id=${combatInfo.id}`,
});

已尝试的解决方法

  • 修改React及配置中的IP地址(如localhost:8080、127.0.0.1:8080等)
  • 移除Socket.io URL中的端口
  • 调整Nginx配置参数
  • 将eventlet替换为gevent

解决方案

核心问题分析

报错显示前端尝试直接连接localhost:8080,但生产环境中前端运行在用户浏览器,localhost指向用户本地而非部署服务器,导致连接被拒绝。同时Nginx的WebSocket配置存在细节缺失,后端CORS设置也不符合生产环境需求。

具体修复步骤

  1. 修正前端Socket.io连接地址
    前端应连接Nginx监听的8000端口,使用相对路径自动适配当前页面的域名和端口,避免硬编码:

    socket = io("/", {
        transports: ["websocket"],
        cors: {
            origin: window.location.origin,
        },
        query: `combat_id=${combatInfo.id}`,
    });
    
  2. 完善Nginx的WebSocket代理配置
    添加超时设置,并修正proxy_pass路径的拼接问题:

    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;
                proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header   X-Forwarded-Proto $scheme;
        }
        
        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_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;
                # 添加WebSocket超时设置
                proxy_connect_timeout 7d;
                proxy_send_timeout 7d;
                proxy_read_timeout 7d;
        }
    }
    
  3. 更新后端CORS及SocketIO配置
    生产环境中cors_allowed_origins应设置为服务器公网域名/IP,或允许前端实际访问的地址:

    # __init__.py中修改SocketIO初始化
    socketio = SocketIO(app, cors_allowed_origins="*", logger=True, engineio_logger=True)
    # 或更严格指定前端地址,如"https://your-domain.com"
    

    同时确保Flask-CORS配置生效:

    CORS(app)
    
  4. 验证后端启动状态
    确认eventlet已正确安装:

    pip install eventlet
    

    通过curl http://127.0.0.1:8080验证后端服务是否在127.0.0.1:8080正常运行。


内容的提问来源于stack exchange,提问作者Elanaris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 09:55:09