通过websockets发送popen的输出

Dav*_*hen 17 php websocket

我正在使用popen和fgets来异步读取tcpdump的输出.

下面的代码应该在命令行中运行,而不是使用apache并在浏览器中查看.

$handle = popen('tcpdump -nnX', 'r');

while (true) {
    $output = fgets($handle);
    print $output . "\n";
}
Run Code Online (Sandbox Code Playgroud)

当我尝试通过websockets输出此信息时出现问题.

Websockets还使用无限循环(用于管理其套接字,刻度和消息).

它看起来像:

while (true) {
    @socket_select($read,$write,$except,1);
    foreach ($read as $socket) {
        if ($socket == $this->master) {
            $client = socket_accept($socket);
...
Run Code Online (Sandbox Code Playgroud)

我使用$ websocket-> sendToAll($ message);通过websocket发送数据.

  • 我不能一个接一个地放入while循环,因为它只会运行我先放入的循环,while (true) { A() }; while (true) { B() };B()永远不会被调用

  • 我无法合并while循环,因为websockets减慢了popen的读取速度,反之亦然.while (true) { A(); B(); }如果B需要很长时间才能完成,A将会很慢.

在这种情况下我该怎么办?我对线程,分叉脚本之间的通信或其他任何东西的想法持开放态度.

Meh*_*ran 7

这是Producer-Consumer问题的经典场景.只是你有两个.您可以分解问题以更容易理解.

  • WebSocket Consumer:此代码将通过WebSocket发送数据.您可以将此视为一个单独的线程,其中数据从Q1(仅仅是名称)出列并发送.

  • WebSocket Producer:一旦某些数据到达WebSocket门,它就会被排入缓冲区.只是这与上面的队列不同.我们来命名吧Q2.这也需要是一个单独的线程,一旦它将数据排入队列并向适当的消费者发出信号,该线程就会进入休眠状态.

  • HDD Consumer:此代码与WebSocket Consumer相同,唯一的区别是它将数据存储在硬盘而不是WebSocket上.它将拥有自己的线程并可以使用Q2.

  • 硬盘制作人:我相信你能猜出这是做什么的.此代码将从硬盘读取数据并将其放入Q1队列中.与所有生产商一样,它需要向消费者发出信号,告知他们队列中的新项目.

现在回到你的代码,PHP不适合多线程编程,即使它是完全可能的.这就是为什么你找不到那么多的例子.但如果你坚持,这就是你需要的:

  1. PHP的Thread类

  2. PHP的Mutex类.此类将帮助您防止多个线程同时访问相同的数据.

  3. Signaling我在PHP中找不到的东西!它用于告诉其他线程队列中的某些数据已准备好被消耗,或者换句话说,它会在消息传递线程有事情时唤醒它.

最后一句话是,在适当的多线程软件中,您将不会使用sleep函数来降低系统的负载/防止系统崩溃.多线程编程是关于线程之间的信令和对话.