PHP可以异步使用套接字吗?

PHP可以异步使用套接字吗?,php,sockets,scripting,asynchronous,webserver,Php,Sockets,Scripting,Asynchronous,Webserver,典型的PHP套接字功能是同步的,并在等待传入连接和数据时停止线程。(如和) 如何异步执行相同的操作?因此,我可以响应数据接收事件中的数据,而不是轮询数据等。是的,这就是socket\u set\u nonblock()的用途。考虑到错误代码11、eWoldBlock和115、EINPROGRESS所假定的特殊含义,您的套接字交互代码需要以不同的方式编写 以下是一些虚构的PHP同步套接字轮询循环示例代码,如请求所示: $buf = ''; $done = false; do { $chun

典型的PHP套接字功能是同步的,并在等待传入连接和数据时停止线程。(如和)


如何异步执行相同的操作?因此,我可以响应数据接收事件中的数据,而不是轮询数据等。

是的,这就是
socket\u set\u nonblock()
的用途。考虑到错误代码11、
eWoldBlock
和115、
EINPROGRESS
所假定的特殊含义,您的套接字交互代码需要以不同的方式编写

以下是一些虚构的PHP同步套接字轮询循环示例代码,如请求所示:

$buf = '';
$done = false;
do {
    $chunk = socket_read($sock, 4096);
    if($chunk === false) {
        $error = socket_last_error($sock);
        if($error != 11 && $error != 115) {
            my_error_handler(socket_strerror($error), $error);
            $done = true;
        }
        break;
    } elseif($chunk == '') {
        $done = true;
        break;
    } else { 
        $buf .= $chunk;
    }
} while(true);

AFAIKPHP是严格单线程的,这意味着不能异步执行,因为脚本执行总是线性的

我已经有一段时间没有这样做了,但据我回忆,您只能打开套接字,并让脚本在收到数据后继续执行

如何异步执行相同的操作? 这样我就可以在数据仓库中对数据做出响应 已接收事件,而不是轮询 数据等

您需要执行脚本并发出stream_select以检查是否有任何数据要接收。处理并发回数据。

术语“异步”在网络编程中经常被误用。对于I/O,异步通常只是用作非阻塞的另一个词。这意味着该过程能够在网络api调用完成传输之前继续

对于一般的进程执行,异步意味着可以同时计算多条指令

换句话说,异步I/O并不是真正的异步,除非使用多个线程来允许多个读/写/接受同时发生-所有套接字都必须等待同步非阻塞调用,如果它有数据要读/写,或者不会阻塞,如果不中断的话,读/写一个大文件仍然需要几秒钟甚至几分钟。请注意,这需要客户端和服务器之间有一个完美的流,否则TCP本身将中断传输。例如,服务器发送速度快于客户端下载速度会导致写操作阻塞

因此,从严格的角度来看,PHP不能执行异步网络,只能执行非阻塞。简言之,当网络呼叫能够有效地读/写等时,进程的进程将停止。但是,当呼叫不能有效地读/写或阻塞时,进程将继续。在一个真正的异步系统中,进程将继续进行,而读/写将在不同的线程中完成。请注意,如果在不同的线程中执行,阻塞I/O仍然可以异步执行

此外,如果不安装支持事件驱动I/O的扩展,PHP无法进行事件驱动I/O。否则,您将需要执行某种形式的轮询,以便在PHP中执行非阻塞I/O。如果使用socket_select,则来自混沌的代码将是一个功能性的非阻塞读取示例


尽管如此,select函数仍然允许PHP中真正的非阻塞行为。在C语言中,轮询服务比事件驱动的服务有性能损失,所以我相信PHP也是如此。但是这种损失是以纳秒为单位的,取决于套接字的数量,非阻塞呼叫所节省的时间通常是毫秒,如果呼叫是等待的话,甚至是秒。

你说的不同是什么意思?您能给我看一些异步数据接收事件的代码示例吗?所以这是同步的,但不是阻塞的?那么非阻塞到底意味着什么呢?不,它是异步的,并且是基于轮询的。代码来自更大的轮询机制。据我所知,PHP不支持您要求的中断/信号驱动套接字I/O事件。通过使用不等待完成但在操作未准备好时立即返回并带有指示错误代码的操作来实现异步通信。类似于非阻塞套接字上的读取。有很多关于C中异步套接字使用的教程将详细介绍这方面的内容;PHP的支持只不过是标准C语言的一层而已。您认为该方法是否按照OP希望的方式进行了更新/改进?是否有人可以发布Infinity非阻塞接收数据的示例代码?please?PHP为异步套接字操作提供stream_select,类似于posix select()。select()是同步的:它只是让您知道套接字是否已准备好读/写。您仍然从单个线程调用它,并阻塞select()调用,而不是read()或write()。stream_select与ops问题几乎没有关系。流(即底层套接字)需要设置为非阻塞,并且需要保留适当的缓冲区(如果在阻塞事件之前只接收到1456中的192个字节会怎么样..如果没有缓冲这192个字节以便在下次读取时继续,它们将丢失)。即使这样,它也不是异步的,只是非阻塞的。