最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

php - WebSocket handshake not working - Stack Overflow

matteradmin5PV0评论

I'm making a simple WebSocket server in PHP. My websocket client connects to it fine, but any time I try to send data through it I get an "Error: INVALID_STATE_ERR: DOM Exception 11" thrown in JavaScript.

This and a couple other questions seem to describe the same problem I'm having but the WebSocket protocol has changed since.

I'm assuming the problem is that my script is handshaking incorrectly as stated in that question. I'm using Chromium 15 which uses WebSocket version 8.

Here's my handshake function (partially my code partially modified from an outdated example I found somewhere):

function dohandshake($user, $buffer)
{
server_log(1, 'Requesting handshake...');

// Determine which version of the WebSocket protocol the client is using
if(preg_match("/Sec-WebSocket-Version: (.*)\r\n/ ", $buffer, $match))
    $version = $match[1];
else 
    return false;

if($version == 8)
{
    // Extract header variables
    if(preg_match("/GET (.*) HTTP/"   ,$buffer,$match)){ $r=$match[1]; }
    if(preg_match("/Host: (.*)\r\n/"  ,$buffer,$match)){ $h=$match[1]; }
    if(preg_match("/Sec-WebSocket-Origin: (.*)\r\n/",$buffer,$match)){ $o=$match[1]; }
    if(preg_match("/Sec-WebSocket-Key: (.*)\r\n/",$buffer,$match)){ $k = $match[1]; }

    // Generate our Socket-Accept key based on the IETF specifications
    $accept_key = $k . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
    $accept_key = sha1($accept_key, true);
    $accept_key = base64_encode($accept_key);

    $upgrade =  "HTTP/1.1 101 Switching Protocols\r\n" .
                    "Upgrade: websocket\r\n" .
                    "Connection: Upgrade\r\n" .
                    "Sec-WebSocket-Accept: $accept_key";

    socket_write($user->socket, $upgrade, strlen($upgrade));
    $user->handshake = true;
    return true;
}
else 
{
    server_log("Client is trying to use an unsupported WebSocket protocol ({$version})");
    return false;
}
}

I tested the key generation code on several examples I found and it seems to have returned the correct key according to those examples

I'm making a simple WebSocket server in PHP. My websocket client connects to it fine, but any time I try to send data through it I get an "Error: INVALID_STATE_ERR: DOM Exception 11" thrown in JavaScript.

This and a couple other questions seem to describe the same problem I'm having but the WebSocket protocol has changed since.

I'm assuming the problem is that my script is handshaking incorrectly as stated in that question. I'm using Chromium 15 which uses WebSocket version 8.

Here's my handshake function (partially my code partially modified from an outdated example I found somewhere):

function dohandshake($user, $buffer)
{
server_log(1, 'Requesting handshake...');

// Determine which version of the WebSocket protocol the client is using
if(preg_match("/Sec-WebSocket-Version: (.*)\r\n/ ", $buffer, $match))
    $version = $match[1];
else 
    return false;

if($version == 8)
{
    // Extract header variables
    if(preg_match("/GET (.*) HTTP/"   ,$buffer,$match)){ $r=$match[1]; }
    if(preg_match("/Host: (.*)\r\n/"  ,$buffer,$match)){ $h=$match[1]; }
    if(preg_match("/Sec-WebSocket-Origin: (.*)\r\n/",$buffer,$match)){ $o=$match[1]; }
    if(preg_match("/Sec-WebSocket-Key: (.*)\r\n/",$buffer,$match)){ $k = $match[1]; }

    // Generate our Socket-Accept key based on the IETF specifications
    $accept_key = $k . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
    $accept_key = sha1($accept_key, true);
    $accept_key = base64_encode($accept_key);

    $upgrade =  "HTTP/1.1 101 Switching Protocols\r\n" .
                    "Upgrade: websocket\r\n" .
                    "Connection: Upgrade\r\n" .
                    "Sec-WebSocket-Accept: $accept_key";

    socket_write($user->socket, $upgrade, strlen($upgrade));
    $user->handshake = true;
    return true;
}
else 
{
    server_log("Client is trying to use an unsupported WebSocket protocol ({$version})");
    return false;
}
}

I tested the key generation code on several examples I found and it seems to have returned the correct key according to those examples

Share Improve this question edited May 23, 2017 at 11:53 CommunityBot 11 silver badge asked Nov 17, 2011 at 3:27 DWilliamsDWilliams 4518 silver badges22 bronze badges 2
  • Dare I ask why on earth you're writing a (hopefully) highly available server in PHP??... :) – Demian Brecht Commented Nov 17, 2011 at 3:35
  • Because I can :) (well, the fact that I'm posting this question might imply that I can't but that's not the point) – DWilliams Commented Nov 17, 2011 at 4:15
Add a ment  | 

1 Answer 1

Reset to default 5

Dumb solution of the century, apparently two "\r\n" newlines are expected at the end of the handshake response.

Post a comment

comment list (0)

  1. No comments so far