如何通过stream_get_contents()连续监听多个TCP流? [英] How to listen muliple TCP streams continously by stream_get_contents()?

查看:115
本文介绍了如何通过stream_get_contents()连续监听多个TCP流?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

默认情况下,stream_get_contents等待等待60秒. 如果我有多个流,并且想要连续收听所有流.

By Default stream_get_contents waits and listen for 60 seconds. if i have multiple streams and want to listen all of them continuously.

在foreach内部,如果我正在收听一个流,则无法收听其他流.

Inside foreach if i am listening one stream, i can't listen other ones.

连续侦听和捕获所有流的流输出的解决方案是什么?

What is the solution to listen and capture stream output for all streams continuously?

while(true){
   //$streamArray is an array of streams obtained by stream_socket_client("tcp://..);
   foreach($streamArray as $stream){
        fputs($stream,$command);
        stream_get_contents($stream);  // and update file/DB (Blocking call)
        }
    }

注意:对于我已经完成的每个流stream_set_blocking( $stream , true );

Note: For every stream i have already done stream_set_blocking( $stream , true );

更新:

我的要求是收听所有流一段时间,例如30分钟.同时我听不到2流.如果我有5个流,我的代码就是time division multiplexing,则在30个薄荷糖中,每个单独的流只会记录6个薄荷糖

My requirement is to listen all streams for some time say 30 mints. at the same time i can't listen 2 stream. if i have 5 streams, my code is just time division multiplexing, out of 30 mints each individual stream will be recorded only for 6 mints

我有一个解决方案,可以对单个流进行AJAX请求并独立记录. 当然,我不想执行这种多重AJAX调用方法,因为它将导致更多的代码以及更多的CPU.

I have one solution that make AJAX request for individual stream and record independently. Certainly i don't want to do this multiple AJAX call method as it will result in more code as well as more CPU.

推荐答案

,您开始同步读取,这意味着对fread()的每次调用都会等到有要读取的数据.然后,您调用stream_get_contents(),它从阻塞流中读取数据直到到达EOF(已关闭).结果是您一次又一次地而不是同时"读取流.

with stream_set_blocking($resource, true) you start reading the stream(s) synchronously, which means each call to fread() waits until there is data to read. You then invoke stream_get_contents(), which reads from the blocking stream until it reaches EOF (is closed). The result is that you read one stream after another and not "simultaneously".

以这种方式读取流是常见的并且最容易编写代码,但是当您要同时处理多个流时,必须自己处理缓冲区,计时和流结束"检测.在您当前的代码中,这部分通过阻塞流和stream_get_contents()从您身上抽象出来.

Reading streams this way is common and the easiest to code, but when you want to handle multiple streams simultaneously, you must handle the buffers, timing and "end of stream" detection yourself. With your current code this part is abstracted away from you via blocking streams and stream_get_contents().

要同时读取多个流,您应该重写代码以异步地读取流.

To read multiple streams simultaneously, you should rewrite your code to read the stream(s) asynchroneously.

未经测试的伪示例:

// $streamArray is an array of streams obtained by stream_socket_client("..");

$buffers = array();
$num_streams = 0;
foreach($streamArray as $stream) {
    // set streams non-blocking for asynchroneous reading
    stream_set_blocking($stream, false);
    // write command to all streams - multiplexing
    fputs($stream, $command);
    // initialize buffers
    $buffers[$stream] = '';
    $num_streams++;
}
while($num_streams) {
    // use stream_select() to wait for new data and not use CPU at 100%.
    // note that the stream arrays are passed by reference and are modified
    // by stream_select() to reflect which streams are modified / have a
    // new event. Because of this we use a copy of the original stream array.
    // also note that due to a limitation in ZE you can not pass NULL directly
    // for more info: read the manual
    $no_stream = NULL;
    $select_read = $streamArray;
    stream_select($select_read, $no_stream, $no_stream, null);

    // if there is new data, read into the buffer(s)
    foreach($select_read as $stream) {
        $buffers[$stream] .= fread($stream, 4096);
        // check if the stream reached end
        if (feof($stream)) {
            $key = array_search($stream, $streamArray);
            // close stream properly
            $num_streams--;
            fclose($stream);
            // remove stream from array of open streams
            unset($streamArray[$key]);
        }
    }
}
// do something with your buffers - our use them inside the while() loop already
print_r($buffers);

这篇关于如何通过stream_get_contents()连续监听多个TCP流?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆