通过websockets

时间:2015-09-12 10:50:45

标签: php websocket

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

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

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

while (true) {
    $output = fgets($handle);
    print $output . "\n";
}

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

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

它看起来像:

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

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

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

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

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

2 个答案:

答案 0 :(得分:7)

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

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

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

  • HDD Consumer :此代码与WebSocket Consumer相同,唯一的区别是它会将数据存储在硬盘而不是WebSocket上。它将拥有自己的主题并与Q2一起使用。

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

现在回到你的代码,即使it's completely possible,PHP也不适合多线程编程。这就是为什么你找不到那么多的例子。但如果你坚持,这就是你需要的:

  1. PHP's Thread class

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

  3. 在PHP中找不到我无法找到的Signaling!它被使用了 告诉其他线程队列中的某些数据已准备就绪 消耗,或换句话说,它将唤醒消费者线程 当它有事可做时。

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

答案 1 :(得分:2)

wscat怎么样?以下命令行:

$ printf "hello\\nbye\\n^C" | wscat -c ws://echo.websocket.org

将以下两行发送到ws://echo.websocket.org

hello
bye

请注意,命令行中的^C是Control-C(不是^C的双字母组合。)