Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/247.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在两个PHP脚本之间传递活动套接字_Php_Multithreading_Sockets_Asynchronous_Websocket - Fatal编程技术网

在两个PHP脚本之间传递活动套接字

在两个PHP脚本之间传递活动套接字,php,multithreading,sockets,asynchronous,websocket,Php,Multithreading,Sockets,Asynchronous,Websocket,我正在用PHP编写一个websocket服务器,它需要能够处理大量并发连接。我目前正在使用socket_select函数来处理它们,但在向客户端发送大数据块时,它仍然会阻止所有其他连接。主脚本是否有办法接受传入的套接字,然后启动第二个PHP脚本(显然是以非阻塞方式),并将客户端套接字传递给该脚本进行处理?我知道这在C语言中是可能的,但可悲的是,由于代码库的原因,迁移是不可能的 *服务器仅在Unix堆栈上运行,不需要MS兼容的解决方案 答案与在C-fork()中使用的答案相同。分叉时,所有打开的文

我正在用PHP编写一个websocket服务器,它需要能够处理大量并发连接。我目前正在使用socket_select函数来处理它们,但在向客户端发送大数据块时,它仍然会阻止所有其他连接。主脚本是否有办法接受传入的套接字,然后启动第二个PHP脚本(显然是以非阻塞方式),并将客户端套接字传递给该脚本进行处理?我知道这在C语言中是可能的,但可悲的是,由于代码库的原因,迁移是不可能的


*服务器仅在Unix堆栈上运行,不需要MS兼容的解决方案

答案与在C-fork()中使用的答案相同。分叉时,所有打开的文件和端口的状态都会保留,因此子进程可以读取父进程打开的端口(这与现代Web服务器为每个进入的客户端连接派生工作线程的方式相同),它确实需要使用pcntl(进程控制)默认情况下禁用的模块,应节约使用,但它可以工作:

if($verbose)
    echo "Connected Client from $remoteaddy to $localaddy\n";
echo "Forking...";
$pid = pcntl_fork(); // you're bringing children into this world, just to kill them in a few seconds. You monster. 
if($pid==0){
            $p = posix.getpid();
    echo "PID OF CHILD: $p\n";
    //in child process. Send a handshake and wait for the callback from the WebSockets library 
    $this->send($client, "Thank you for contacting myAwesomeServer.com! I'm slave #{$p}, and I'll be your host today");  
}else if($pid>0){
    $childWorkers[]=$pid;
    echo "[ OK ]\n";
    $this->disconnect($client->socket, false); //disconnect the clients socket from the master thread, so only the child thread is talking to the client

}else if($pid==-1){
    echo "[FAIL] unable to create child worker\n";
}
注意!!这种方法纯粹是学术性的,只有在您没有足够的时间学习更合适的语言时,才应该在小型的“宠物”项目上使用(就个人而言,我对C非常了解fork(),但我对其字符串操作函数的了解不足无疑会在服务器上留下一个巨大的安全漏洞)。我不确定Zend引擎是如何实现这个pcntl_fork(),但我可以想象,这个怪物的内存映像将是等效C代码大小的许多倍

我目前正在使用socket_select函数来处理它们,但在向客户端发送大数据块时,它仍然会阻止所有其他连接

然后不要一次发送所有数据。如果你打算

socket_write ($mysocket, $mybuffer, 10000000);
然后是的,你必须等到所有1000万字节都被发送出去。但是,您可以使用
socket\u select
$write
数组检查是否可以与非阻塞套接字一起写入套接字。每次
socket\u select
显示您有一个“开始!”在套接字上写入数据,直到
socket\u write
开始抱怨(即返回FALSE或小于指定长度)。这将使套接字的发送缓冲区保持最佳填充状态


缺点是您必须准确地跟踪您在输出缓冲区中的位置;另外,在写入所有数据后关闭套接字上的非阻塞功能,或者
socket\u select
将继续启动(这假设您要发送多个大数据块)。

您可能可以使其正常工作。。。然而,你有没有考虑过一个更容易实现这一点的平台,比如Node.js?是的,我开始认为我必须修改一个很久以前写的C程序才能让它工作。我的意思是,这是一个我想从事的有趣的项目,但现在我真的没有时间用一种新的语言来提高自己在套接字等方面的速度,并最终得到一个安全的解决方案。为什么它是学术性的?PHP不适合websocket服务器吗?记住在执行Fork时使用的“写时复制”。PHP的fork是通过引擎盖下的同一个系统fork实现的。