最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

reactjs - WebSocket Connection Error with React, Nginx, and Docker Setup - Stack Overflow

programmeradmin4浏览0评论

I am setting up a React application with a backend API and WebSocket server, using Nginx as a reverse proxy. However, my WebSocket client fails to connect to the server, and I get the error: Socket connection error: Failed to connect to the socket server.

Additionally, I want the Nginx configuration to be dynamic so that the same React build works in different environments (local, staging, production) without needing to rebuild the app for each environment.

Here’s my setup:

  1. Nginx Configuration (nginx.conf)

    events {}
    
    http {
        include /etc/nginx/mime.types;
        include /etc/nginx/conf.d/sites-enabled/*.conf;
    
        server {
            set $api_url "http://192.168.1.3:3000"; # Dynamic backend server URL (replaceable for different environments)
            listen 80;
            server_name 192.168.1.3;
    
            location / {
                root /usr/share/nginx/html;
                index index.html index.htm;
                try_files $uri $uri/ /index.html;
            }
    
            location /api {
                rewrite ^/api/(.*)$ /$1 break;
                proxy_pass $api_url;
                proxy_http_version 1.1;
                proxy_set_header Connection '';
                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;
            }
    
            location /socket.io/ {
                proxy_pass $api_url;
                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;
                proxy_read_timeout 600s;
                proxy_send_timeout 600s;
            }
    
            location /static {
                root /usr/share/nginx/html;
            }
        }
    }
    
  2. Docker Compose Configuration (docker-compose.yml)

    version: "3.8"
    services:
      web:
        image: nginx:alpine
        container_name: web-app
        ports:
          - "5000:80"
        volumes:
          - ./build:/usr/share/nginx/html:ro
          - ./nginx.conf:/etc/nginx/nginx.conf:ro
        environment:
          - NODE_ENV=production
        restart: always
    
  3. React .env File

    REACT_APP_API_URL=/api
    REACT_APP_SOCKET_HOST=
    
  4. Socket Client (socketclient.ts)

    import { io, Socket } from "socket.io-client";
    
    class SocketClient {
      private socket: Socket | null = null;
    
      connect(): Promise<void> {
        return new Promise((resolve, reject) => {
          if (!process.env.REACT_APP_SOCKET_HOST) {
            reject("Socket host is not defined.");
            return;
          }
    
          this.socket = io(process.env.REACT_APP_SOCKET_HOST as string, {
            reconnection: true,
            transports: ["websocket", "polling"],
          });
    
          this.socket.on("connect", () => resolve());
          this.socket.on("connect_error", (error) => {
            console.error("Socket connection error:", error);
            reject(error);
          });
        });
      }
    
      disconnect(): Promise<void> {
        return new Promise((resolve, reject) => {
          if (this.socket) {
            this.socket.disconnect();
            this.socket.once("disconnect", () => {
              this.socket = null;
              resolve();
            });
          } else {
            reject("No socket connection.");
          }
        });
      }
    
      emit(event: string, data: any): Promise<void> {
        return new Promise((resolve, reject) => {
          if (!this.socket) return reject("No socket connection.");
    
          this.socket.emit(event, data, (response: any) => {
            if (response?.error) {
              return reject(response.error);
            }
            resolve();
          });
        });
      }
    
      on(event: string, callback: (data: any) => void): void {
        if (!this.socket) throw new Error("No socket connection.");
        this.socket.on(event, callback);
      }
    }
    
    export default new SocketClient();
    
  5. Observed Behavior

    1. The React frontend loads properly.

    2. API requests (/api) proxied through Nginx work as expected.

    3. WebSocket connections (socket.io) fail with the error:

      Socket connection error: Failed to connect to the socket server
      
发布评论

评论列表(0)

  1. 暂无评论