如何在使用zlib过滤器时使用PHP的stream_select()函数?

6

我目前有一个用PHP编写的服务器守护进程,它接受传入的连接并使用stream_socket_*函数为它们创建网络流,并使用stream_select()轮询活动流。我想能够向任意流添加zlib过滤器(使用string_filter_append()),但是当我这样做时,会出现错误提示,告诉我不能使用stream_select()来轮询过滤流。

我该如何规避这个限制?

1个回答

3

您可以使用管道,将过滤器添加到管道中。

这将允许您在流上使用stream_select,并且该管道将作为zlib的缓冲区。

从select()ed流中读取原始数据,将其写入管道中,并在另一侧读取解码后的数据 :)

list($in, $out) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, 0);

stream_filter_append($out, 'zlib.inflate', STREAM_FILTER_READ);
stream_set_blocking($out, 0);

while (stream_select(...)) {
    // assuming that $stream is non blocking
    stream_copy_to_stream($stream, $in);

    $decoded_data = stream_get_contents($out);
}

可能可以使用php:// memory流来实现相同的功能。

谢谢,这种方法似乎确实可以让我绕过限制,但是我正在使用“zlib.deflate”,而且我不是复制流到流,而是只使用fwrite()将服务器生成的数据通过出站网络流发送。使用这种方法,stream_get_contents($out)返回2字节的zlib头,什么都没有。如果我将相同的数据写入文件,而不是写入$in并读取$out,则压缩的$data会完全写入。这种方法有什么可能阻止从$out中读取完整的压缩数据吗? - drrcknlsn
过滤器可能只在写入一定量的数据后才会写入流;尝试写入更多数据。还可以尝试使用zlib.deflate过滤器,在写入端使用STREAM_FILTER_WRITE,或在读取端使用STREAM_FILTER_READ。 - Arnaud Le Blanc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接