从结构上讲,线程是解决这个问题的好方法,所以你肯定会以正确的方式思考这个问题。不幸的是,PHP不支持线程!所以,您必须使用进程,而不是通过pcntl_fork()
。 Here's an example(不是我的代码),创建一个新的进程来处理每个连接而不是一个线程。
/**
* Connection handler
*/
function onConnect($client) {
$pid = pcntl_fork();
if ($pid == -1) {
die('could not fork');
} else if ($pid) {
// parent process
return;
}
$read = '';
printf("[%s] Connected at port %d\n", $client->getAddress(), $client->getPort());
while(true) {
$read = $client->read();
if($read != '') {
$client->send('[' . date(DATE_RFC822) . '] ' . $read );
}
else {
break;
}
if(preg_replace('/[^a-z]/', '', $read) == 'exit') {
break;
}
if($read === null) {
printf("[%s] Disconnected\n", $client->getAddress());
return false;
}
else {
printf("[%s] recieved: %s", $client->getAddress(), $read);
}
}
$client->close();
printf("[%s] Disconnected\n", $client->getAddress());
}
require "sock/SocketServer.php";
$server = new \Sock\SocketServer();
$server->init();
$server->setConnectionHandler('onConnect');
$server->listen();
你说你还需要一个线程来发送keepalives。我会说最简单的解决方案是pnctl_fork()
一个额外的过程,并用它来发送keepalive,而其他进程很忙。
至于keepalive消息,您可以在分叉连接处理程序进程中执行此操作。然后,在连接处理程序进程下的另一个分叉进程中执行实际的工作。
请注意,这是一个非常宽泛的问题,所以很难用更具体的答案。 – Will
好吧 - 我也读过pcntl_fork()。但是,只要我的客户端连接到代理服务器,该线程只会持续多久?例如,我的客户端连接 - >一个新的进程开始处理客户端 - >客户端断开连接 - >进程结束。 – derp
当客户端断开连接时,进程不会自动死掉。如果客户端在工作完成之前断开连接,那么工作进程池应该完全独立,客户端只需与后台工作进程使用的队列进行交互。 – Will