有没有办法在 PHP 中执行 do、while 循环时监听新的套接字连接?
Posted
技术标签:
【中文标题】有没有办法在 PHP 中执行 do、while 循环时监听新的套接字连接?【英文标题】:Is there a way to listen for new socket connections while doing a do, while loop in PHP? 【发布时间】:2021-09-12 20:03:53 【问题描述】:我正在尝试制作一个简单的 php、javascript websocket 测试项目,但我遇到了一旦我调用套接字接受函数,PHP 将不会继续 while(true) 循环的问题。它在继续循环之前等待实际连接。有没有办法异步调用它,以便 while 循环可以继续?或者有没有办法在一个被接受后立即接受更多的传入连接? 这是我的代码
<?php
error_reporting(E_ALL);
/* Allow the script to hang around waiting for connections.
set_time_limit(0);
/* Turn on implicit output flushing so we see what we're getting
as it comes in.
ob_implicit_flush();*/
$address = 'localhost';
$port = 8080;
$clients = [];
$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);
/*$client = acceptConn($server);
$clients[0] = $client;*/
// Send WebSocket handshake headers.
$newclient = socket_accept($server);
handshake($server, $newclient);
$clients[count($clients)] = $newclient;
function handshake($server, $client)
$request = socket_read($client, 5000);
preg_match('#Sec-WebSocket-Key: (.*)\r\n#', $request, $matches);
$key = base64_encode(pack(
'H*',
sha1($matches[1] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')
));
$headers = "HTTP/1.1 101 Switching Protocols\r\n";
$headers .= "Upgrade: websocket\r\n";
$headers .= "Connection: Upgrade\r\n";
$headers .= "Sec-WebSocket-Version: 13\r\n";
$headers .= "Sec-WebSocket-Accept: $key\r\n\r\n";
socket_write($client, $headers, strlen($headers));
// Send messages into WebSocket in a loop.
do
sleep(1);
//echo "next";
$content = 'Now: ' . time();
$response = chr(129) . chr(strlen($content)) . $content;
foreach($clients as $key => $item)
if(socket_write($item, $response) != 17)
socket_close($item);
unset($clients[$key]);
continue;
//echo json_encode($clients);
continue;
/*echo count($clients);
$newclient = socket_accept($server);
echo gettype($newclient);
$clients[count($clients)] = $client;*/
while (true);
?>
【问题讨论】:
【参考方案1】:我找到了解决方案。 对于任何想知道它是什么的人,请使用:
socket_set_nonblock($socketservervariable);
使服务器在继续之前不等待客户端连接。但是,这会产生一个新错误。在进行客户端握手时,socket_read 想要一个套接字,但是当 socket_accept 函数没有检测到客户端连接时,它得到了布尔值 false。所以这是我的解决方案:
$newclient = socket_accept($server);
if($newclient != false)
handshake($server, $newclient);
$clients[count($clients)] = $newclient;
echo "\n\nNew client connected!\n\n";
这解决了我所有的问题。
【讨论】:
以上是关于有没有办法在 PHP 中执行 do、while 循环时监听新的套接字连接?的主要内容,如果未能解决你的问题,请参考以下文章