You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于WebSocket的视频聊天项目服务器连接400错误排查求助

Fixing WebSocket Handshake Error 400 with NGINX & Socket.io for P2P Video Chat

Hey there, let's work through this WebSocket handshake error you're facing. Localhost works perfectly, so the issue is almost certainly tied to how NGINX is proxying your Socket.io/WebSocket traffic. Let's break down the fixes step by step:

1. Fix NGINX Configuration (Critical!)

Socket.io uses HTTP upgrade requests to switch from HTTP to WebSocket, and NGINX needs explicit config to handle this. Here's a complete, Socket.io-compatible NGINX block for your domain:

server {
    listen 443 ssl;
    server_name tensy.org;

    # Your existing SSL config (keep this!)
    ssl_certificate /path/to/your/ssl/cert.pem;
    ssl_certificate_key /path/to/your/ssl/key.pem;

    # Proxy for Socket.io namespace /space
    location /space {
        proxy_pass http://localhost:YOUR_NODE_SERVER_PORT; # Replace with your actual Node port
        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;

        # Long timeouts for video chat (avoids unexpected disconnects)
        proxy_connect_timeout 7d;
        proxy_send_timeout 7d;
        proxy_read_timeout 7d;
    }

    # Serve your React build files
    location / {
        root /path/to/your/react/app/build;
        try_files $uri $uri/ /index.html;
    }
}

Key Config Notes:

  • proxy_http_version 1.1 and the Upgrade/Connection headers are mandatory for WebSocket handshake to work.
  • The long timeout values prevent NGINX from dropping the persistent video chat connection.
  • Double-check that proxy_pass points to your running Node.js server's correct port.

2. Validate Socket.io Server Setup

Make sure your Node.js server is configured to handle CORS (even for same-domain, it's safe to explicitly allow) and the /space namespace:

const io = require('socket.io')(yourServerInstance, {
  cors: {
    origin: "https://tensy.org",
    methods: ["GET", "POST"]
  }
});

// Initialize the /space namespace
const spaceNamespace = io.of('/space');
spaceNamespace.on('connection', (socket) => {
  console.log('User connected to space namespace');
  // Handle your call/answer/candidate events here
});

3. Clean Up React Component Code

Your component has a few anti-patterns that could contribute to timing issues:

Replace componentWillMount with componentDidMount

componentWillMount is deprecated in React 17+ and runs before the DOM is ready. Switch to componentDidMount to ensure elements like <video id="local"> exist before you try to access them:

componentDidMount() {
  let _position = document.location.pathname.split('/').pop();
  console.log(_position);
  
  // All your WebRTC/Socket.io setup code goes here...
}

Remove $(document).ready() Wrappers

React's lifecycle already ensures the DOM is ready when componentDidMount runs. The jQuery wrapper can delay socket event listeners, leading to missed handshake messages:

// Instead of this:
$(document).ready(function() {
  socket.on('answer', function(mes) { ... });
});

// Do this directly in componentDidMount:
socket.on('answer', (mes) => {
  console.log('Client 1', mes);
  peer.setRemoteDescription(JSON.parse(mes['description']))
    .then(() => addcandidate(candidatee));
});

Fix the addcandidate Recursion

Your current addcandidate function can loop infinitely if candidatee never arrives. Add a retry limit to prevent this:

function addcandidate(data, retries = 0) {
  console.log('Candidate', data);
  setTimeout(() => {
    if (candidatee) {
      console.log('!', candidatee);
      peer.addIceCandidate(JSON.parse(candidatee));
    } else if (retries < 10) { // Max 10 retries (adjust as needed)
      addcandidate(data, retries + 1);
    } else {
      console.error('Failed to retrieve ICE candidate after multiple attempts');
    }
  }, 100);
}

4. Troubleshooting Steps if Issues Persist

  • Check NGINX error logs (/var/log/nginx/error.log) for specific handshake failure details.
  • Use your browser's Network tab to inspect the WebSocket request: verify the Upgrade: websocket and Connection: upgrade headers are present in the request, and that the response doesn't have additional error context.
  • Confirm your Node.js server is running and accessible directly (try hitting http://tensy.org:YOUR_NODE_PORT/space to see if it responds).

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

火山引擎 最新活动