客户端无法收到握手信息

想写一下websocket,但是无论如何收不到捂手信息,找了好久,有人给瞅瞅吗,chrome一直显示pending,代码如下:
$address = '0.0.0.0';

$port = '8081';

$sockets = [];


$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1);

socket_bind($server, $address, $port);

socket_listen($server, 10);

array_push($sockets, $server);


while (true) {
$write = null;
$except = null;
socket_select($sockets, $write, $except, null);
foreach ($sockets as $socket) {
if ($socket == $server) {
//等待接受一个链接
$client = socket_accept($socket);

//获取接数据
$buff = socket_read($client, 1024);

//得到请求头中升级ws协议的key
preg_match('/Sec\-WebSocket\-Key:\s(.*)/', $buff, $result);
$wsKey = $result[1];

//编码key 编码方式: 请求头Sec-WebSocket-Key的值 + 固定字符串"258EAFA5-E914-47DA-95CA-C5AB0DC85B11" sha1进行hash后base64编码
$acceptWsKey = base64_encode(pack('H*', sha1($wsKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));

//组合响应头
$responseHttpHeader = 'HTTP/1.1 101 Switching Protocols\r\n';
$responseHttpHeader .= 'Upgrade: websocket\r\n';
$responseHttpHeader .= 'Connection: Upgrade\r\n';
$responseHttpHeader .= 'Sec-WebSocket-Accept: ' . $acceptWsKey . '\r\n\r\n';
socket_write($client, $responseHttpHeader, strlen($responseHttpHeader));
array_push($sockets, $client);
}
}
}
已邀请:

blogdaren - 喜欢分享的PHP码农【http://www.blogdaren.com】

赞同来自: original

1. 握手期间参考代码:
<?php
$address = '0.0.0.0';
$port = '8081';
$mainSocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($mainSocket, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($mainSocket, $address, $port);
socket_listen($mainSocket, 10);
$read_socks[] = $mainSocket;
$write_socks = array();
$except_socks = NULL;

while(1)
{
$tmp_reads = $read_socks;
$tmp_writes = $write_socks;
$select_result = @socket_select($tmp_reads, $tmp_writes, $except_socks, NULL);
if(false === $select_result) continue;

foreach($tmp_reads as $read)
{
if($read == $mainSocket)
{
$new_socket = @socket_accept($mainSocket);
if(!$new_socket) continue;
$read_socks[] = $new_socket;
$write_socks[] = $new_socket;
}
else
{
$msg = socket_read($read, 1024);
if($msg === '')
{
foreach($read_socks as $k => $v)
{
if($v == $read) unset($read_socks[$k]);
}

foreach($write_socks as $k => $v)
{
if($v == $read) unset($write_socks[$k]);
}
socket_close($read);
}
else
{
//得到请求头中升级ws协议的key
if(!preg_match("/Sec-WebSocket-Key: *(.*?)\r\n/i", $msg, $match)) throw new \Exception('bad request');
$Sec_WebSocket_Key = $match[1];

//编码key 编码方式: 请求头Sec-WebSocket-Key的值 + 固定字符串"258EAFA5-E914-47DA-95CA-C5AB0DC85B11" sha1进行hash后base64编码
$acceptWsKey = base64_encode(sha1($Sec_WebSocket_Key . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true));

//组合响应头
if(in_array($read, $tmp_writes))
{
$responseHttpHeader = "HTTP/1.1 101 Switching Protocols\r\n";
$responseHttpHeader .= "Upgrade: websocket\r\n";
$responseHttpHeader .= "Sec-WebSocket-Version: 13\r\n";
$responseHttpHeader .= "Connection: Upgrade\r\n";
$responseHttpHeader .= "Sec-WebSocket-Accept: " . $acceptWsKey . "\r\n\r\n";
socket_write($read, $responseHttpHeader, strlen($responseHttpHeader));
}
}
}
}
}
2. 命令行测试:
curl --no-buffer -H 'Connection: Upgrade' -H 'Upgrade: websocket' -v -H 'Sec-WebSocket-Version: 13' -H 'Sec-WebSocket-Key: websocket'  http://127.0.0.1:8081 
* About to connect() to 127.0.0.1 port 8081 (#0)
* Trying 127.0.0.1... connected
* Connected to 127.0.0.1 (127.0.0.1) port 8081 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: 127.0.0.1:8081
> Accept: */*
> Connection: Upgrade
> Upgrade: websocket
> Sec-WebSocket-Version: 13
> Sec-WebSocket-Key: websocket
>
< HTTP/1.1 101 Switching Protocols
< Upgrade: websocket
< Sec-WebSocket-Version: 13
< Connection: Upgrade
< Sec-WebSocket-Accept: qVby4apnn2tTYtB1nPPVYUn68gY=

original

赞同来自:

最近正在学习socket   如果问的有点低级 大佬别喷...   

要回复问题请先登录注册