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

无法通过fsockopen连接WebSocket服务器,求PHP连接WebSocket解决方案

Fixing 400 Bad Request When Connecting to WebSocket via PHP

Your current code sends a plain HTTP GET request, but WebSocket connections require a specific handshake process with mandatory headers. That’s exactly why you’re hitting a 400 error—the server doesn’t recognize your request as a valid WebSocket initiation.

Let’s break down what’s missing and fix the code step by step:

Key Issues in Your Original Code

  • You’re using fsockopen for an HTTPS (443) connection, which doesn’t handle SSL/TLS encryption. You need to use stream_socket_client with an SSL context instead.
  • Critical WebSocket handshake headers are missing: Upgrade, Connection, Sec-WebSocket-Key, and Sec-WebSocket-Version are required for the server to switch protocols to WebSocket.

Corrected Working Code

// Create an SSL context for secure HTTPS connection
$context = stream_context_create([
    'ssl' => [
        'verify_peer' => false, // Disable for testing; enable this in production
        'verify_peer_name' => false,
    ]
]);

// Connect to the WebSocket server over SSL
$fp = stream_socket_client('ssl://cs.money:443', $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);

if (!$fp) {
    echo "$errstr ($errno)<br />";
} else {
    // Generate a random key required for WebSocket handshake
    $websocketKey = base64_encode(random_bytes(16));
    
    // Build the proper WebSocket handshake request
    $handshakeRequest = "GET / HTTP/1.1\r\n";
    $handshakeRequest .= "Host: cs.money\r\n";
    $handshakeRequest .= "Upgrade: websocket\r\n";
    $handshakeRequest .= "Connection: Upgrade\r\n";
    $handshakeRequest .= "Sec-WebSocket-Key: $websocketKey\r\n";
    $handshakeRequest .= "Sec-WebSocket-Version: 13\r\n";
    $handshakeRequest .= "\r\n"; // Mark end of headers
    
    // Send the handshake request
    fwrite($fp, $handshakeRequest);
    
    // Read the server's handshake response
    $response = '';
    while (!feof($fp)) {
        $response .= fgets($fp, 1024);
        // Stop reading once we reach the end of headers (double newline)
        if (strpos($response, "\r\n\r\n") !== false) {
            break;
        }
    }
    
    // Verify if handshake was successful
    if (strpos($response, 'HTTP/1.1 101 Switching Protocols') !== false) {
        echo "WebSocket handshake successful!\n";
        // Note: After this, you need to encode/decode messages per WebSocket framing rules
        // (client messages must be masked, server messages are unmasked)
    } else {
        echo "Handshake failed. Server response:\n$response";
    }
    
    fclose($fp);
}

Important Post-Handshake Notes

  1. SSL Security: In production, enable verify_peer and verify_peer_name to ensure secure, verified connections—disabling them is only for testing.
  2. WebSocket Framing: Once the handshake succeeds, you can’t send plain text directly. You need to wrap messages in WebSocket frames (with opcode, length, and masking key for client-to-server messages).
  3. Server-Specific Headers: Some servers may require additional headers like Origin—if you still get errors, inspect browser WebSocket requests (via DevTools) to match the exact headers the server expects.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:26:44