php - pthreads 在 React/Ratchet 中无法按预期工作

标签 php websocket pthreads ratchet

我正在尝试向 Ratchet WebSocket 应用程序添加 pecl-pthreads 多线程支持。

这是我的应用程序:

<?php
namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Chat implements MessageComponentInterface
{
    protected $clients;
    public function __construct()
    {
        $this->clients = new \SplObjectStorage;
    }

    public function onOpen(ConnectionInterface $conn)
    {
        $this->clients->attach($conn);
        echo "New connection! ({$conn->resourceId})\n";
    }

    public function onMessage(ConnectionInterface $from, $msg)
    {
        $dataIn = json_decode($msg);
        switch ($dataIn->type) {
            case 'test1':
                echo '+t1 block start' . date(' H:i:s') . "\n";
                $test1 = new Test1();
                $test1->start();
                echo '+t1 block end' . date(' H:i:s') . "\n";
                break;
            case 'test2':
                echo '-t2 block start' . date(' H:i:s') . "\n";
                $test2 = new Test2();
                $test2->start();
                echo '-t2 block end' . date(' H:i:s') . "\n";
                break;
        }
    }

    public function onClose(ConnectionInterface $conn)
    {
        $this->clients->detach($conn);
        echo "Connection {$conn->resourceId} has disconnected\n";
    }

    public function onError(ConnectionInterface $conn, \Exception $e)
    {
        echo "An error has occurred: {$e->getMessage()}\n";
        $conn->close();
    }
}

这是Test1.php的内容:
<?php
namespace MyApp;
class Test1 extends \Thread
{
    public function run()
    {
        echo '#Test1 thread start' . date(' H:i:s') . "\n";
        for ($i = 0; $i < 2; $i++) {
            echo 1 . date(' H:i:s') . "\n";
            sleep(10);
        }
        echo '#Test1 thread end' . date(' H:i:s') . "\n";
    }
}

这是Test2.php的内容:
<?php
namespace MyApp;
class Test2 extends \Thread
{
    public function run()
    {
        echo '#just Test2 run' . date(' H:i:s') . "\n";
    }
}

这是 JavaScript 代码:
var Websocket = new function () {
    var ws
    this.init = function () {
        ws = new WebSocket(wsURL + '/test')
        ws.onclose = function () {
            setTimeout('Websocket.init()', 1000)
        }
    }
    this.test1 = function () {
        var token = {
            type: 'test1'
        }
        ws.send(JSON.stringify(token))
    }
    this.test2 = function () {
        var token = {
            type: 'test2'
        }
        ws.send(JSON.stringify(token))
    }
}
$(document).ready(function () {
    Websocket.init()
})

var startTest = function () {
    Websocket.test2()
    Websocket.test2()
    Websocket.test1()
    Websocket.test2()
    Websocket.test2()
}

问题是 Test1 线程阻塞了 MyApp 的 onMessage 方法。

当我使用浏览器连接到我的应用程序并运行 JavaScript startTest() 函数时,我得到了这个 CLI 应用程序输出:
-t2 block start 20:08:48
#just Test2 run 20:08:48
-t2 block end 20:08:48
-t2 block start 20:08:48
#just Test2 run 20:08:48
-t2 block end 20:08:48
+t1 block start 20:08:48
#Test1 thread start 20:08:48
+t1 block end 20:08:48
1 20:08:48                                                                                                                                                                                                                                     
1 20:08:58                                                                                                                                                                                                                                     
#Test1 thread end 20:09:08                                                                                                                                                                                                                     
-t2 block start 20:09:08                                                                                                                                                                                                                       
#just Test2 run 20:09:08                                                                                                                                                                                                                       
-t2 block end 20:09:08                                                                                                                                                                                                                         
-t2 block start 20:09:08                                                                                                                                                                                                                       
#just Test2 run 20:09:08                                                                                                                                                                                                                       
-t2 block end 20:09:08

如您所见,我从浏览器向我的应用程序发送了 5 条即时消息。但是在 test1 消息之后,onMessage 方法的执行会暂停,直到 Test1 线程的执行结束。是某种 pthreads/Ratchet 错误还是我做错了什么?

最佳答案

您通过一个连接发送消息,这意味着您只有一个线程。
如果您想检查多线程是否正常工作 - 您应该尝试在下一个浏览器窗口/选项卡中运行该 JS。

因为当 test1 阻塞线程时,其他消息(剩下 2 个消息 test2)正在队列中等待。
但是,如果其他人同时连接到服务器,他将不会被阻塞 - 因为他将获得单独的线程。在这种情况下,这就是多线程的威力。

关于php - pthreads 在 React/Ratchet 中无法按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40940351/

相关文章:

PHP/C++ : shm_open() error when sharing memory

php - Paypal 返回 URL - 使用 GET 参数?

php - 检查字符串是否包含数组的任何值?

node.js - Angular 通用服务器渲染 WebSocket

javascript - 未捕获的 DOMException : An attempt was made to use an object that is not, 或在访问可用变量时不再可用

c - 如何在 SIGABRT 信号处理程序中等待

java - 每个请求模型的线程能否比非阻塞 I/O 更快?

c - 线程安全队列的问题表现为 IDE 控制台中没有输出

php - PDO返回了不正确但重复的数据。 key 不在数据库中。

websocket - ws 和 wss 之间的区别?