【问题标题】:Broadcast stream with PHP within localhost在 localhost 中使用 PHP 广播流
【发布时间】:2016-06-18 00:42:29
【问题描述】:

也许我在问不可能,但我想多次克隆一个流。一种多播仿真。这个想法是每 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');
}

很乱。不知道怎么同步chunk的读取过程,觉得sockets可以创造奇迹。

【问题讨论】:

    标签: php broadcast


    【解决方案1】:

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

    使用没有任何流控制的单个文件应该不是问题 - 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() 之外,还涉及更多内容,但有可用的some good 脚本可以为您完成大部分复杂的工作。

    【讨论】:

      猜你喜欢
      • 2011-01-14
      • 1970-01-01
      • 2016-04-28
      • 1970-01-01
      • 1970-01-01
      • 2015-12-25
      • 1970-01-01
      • 1970-01-01
      • 2014-03-02
      相关资源
      最近更新 更多