在本地主机中使用 PHP 广播流



也许我在问不可能的事情,但我想多次克隆流。一种多播仿真。这个想法是每 0.002 秒将一个 1300 字节的大缓冲区写入 .sock 文件(而不是 IP:port 以避免开销),然后从其他脚本多次读取相同的 .sock 文件。通过常规文件执行此操作是不可行的。它仅在生成缓冲区文件然后回显它的同一脚本中工作。其他脚本会严重误读它。

这与生成块的脚本完美配合:

$handle = @fopen($url, 'rb');
$buffer = 1300;
while (1) {
            $chunck = fread($handle, $buffer);
            $handle2 = fopen('/var/tmp/stream_chunck.tmp', 'w');
            fwrite($handle2, $chunck);
            fclose($handle2);
            readfile('/var/tmp/stream_chunck.tmp');
}

但是读取块的另一个脚本的输出:

while (1) {
                readfile('/var/tmp/stream_chunck.tmp');
}

是凌乱的。我不知道如何同步块的读取过程,我认为套接字可以创造奇迹。

它仅在生成缓冲区文件然后回显它的同一脚本中工作。其他脚本会严重误读它

使用没有任何流量控制的单个文件应该不是问题 - tail -F 就是这样做的。缺点是,只要单个客户端具有打开的文件句柄(即使截断文件),数据就会在文件系统上无限期地累积。

但是如果你正在写入块,然后将每个块写入不同的文件(使用原子写入机制),那么每个人都可以通过轮询可用文件来读取它。

do {
   while (!file_exists("$dir/$prefix.$current_chunk")) {
     clearstatcache();
     usleep(1000);
   }
   process(file_get_contents("$dir/$prefix.$current_chunk"));
   $current_chunk++;
} while (!$finished);

同样,您可以使用数据库执行此操作 - 该数据库的轮询开销应该略低,并简化了旧块的垃圾收集。

但这都是关于如何使您的解决方案可行 - 它并没有真正解决您试图解决的问题。如果我们知道您要实现的目标,那么我们也许能够就更合适的解决方案提供建议 - 例如,如果是聊天应用程序,视频广播,其他东西......

我怀疑更合适的解决方案是使用多处理的单内存模型服务器 - 当我们谈论 PHP(它并没有很好地完成线程)时,这意味着基于事件的/异步服务器。这比简单地调用 socket_select() 要复杂一些,但有一些好的脚本可以为您完成大部分复杂的工作。

最新更新