想寫一下websocket,但是無(wú)論如何收不到捂手信息,找了好久,有人給瞅瞅嗎,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) {
//等待接受一個(gè)鏈接
$client = socket_accept($socket);
//獲取接數(shù)據(jù)
$buff = socket_read($client, 1024);
//得到請(qǐng)求頭中升級(jí)ws協(xié)議的key
preg_match('/Sec\-WebSocket\-Key:\s(.*)/', $buff, $result);
$wsKey = $result;
//編碼key 編碼方式: 請(qǐng)求頭Sec-WebSocket-Key的值 + 固定字符串"258EAFA5-E914-47DA-95CA-C5AB0DC85B11" sha1進(jìn)行hash后base64編碼
$acceptWsKey = base64_encode(pack('H*', sha1($wsKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
//組合響應(yīng)頭
$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);
}
}
}
<?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);
}
foreach($write_socks as $k => $v)
{
if($v == $read) unset($write_socks);
}
socket_close($read);
}
else
{
//得到請(qǐng)求頭中升級(jí)ws協(xié)議的key
if(!preg_match("/Sec-WebSocket-Key: *(.*?)\r\n/i", $msg, $match)) throw new \Exception('bad request');
$Sec_WebSocket_Key = $match;
//編碼key 編碼方式: 請(qǐng)求頭Sec-WebSocket-Key的值 + 固定字符串"258EAFA5-E914-47DA-95CA-C5AB0DC85B11" sha1進(jìn)行hash后base64編碼
$acceptWsKey = base64_encode(sha1($Sec_WebSocket_Key . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true));
//組合響應(yīng)頭
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));
}
}
}
}
}
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=
多謝回復(fù),找到問(wèn)題了 上面沒(méi)有握手成功的原因是返回http頭的時(shí)候用的單引號(hào), 而我系統(tǒng)是linux,導(dǎo)致沒(méi)有被解析成換行,所以用PHP_EOL代替\r\n或者雙引號(hào)代替單引號(hào)都可以解決