【问题标题】:PHP Swoole coroutine, async messages not asyncPHP Swoole协程,异步消息不异步
【发布时间】:2021-05-26 16:08:37
【问题描述】:

我正在运行 Swoole WebSocket 服务器,并且我正在尝试在脚本运行时向最终用户发送消息。我遇到的问题是消息不是异步发送的,只有在脚本完成执行后才会发送。哪一种违背了目的。

我的问题的精简版如下:

# Recipient IDs
$fd = [75371];
# Message to recipient
$message = "Ping";

# Let's send the message as a coroutine
go(function() use ($fd, $message){
    print "About to send message [{$message}] to recipients ".json_encode($fd).PHP_EOL;
    # Connect to the WebSocket and send the message
    $client = new \Swoole\Coroutine\Http\Client(0.0.0.0, 1234);
    $client->upgrade("/");
    $client->push(json_encode([
        "fd" => $fd,
        "data" => $message
    ]));
    $client->close();
    print "Finally the message was sent".PHP_EOL;
});

# Coroutine script is done, let's continue with our other tasks
print "But wait, I'm gonna be busy with other tasks for 5 seconds first".PHP_EOL;
sleep(5); // This simulates process intensive tasks

# Another coroutine, not related
go(function() {
    print "Gonna be busy again again for another 5 seconds".PHP_EOL;
    co\System::sleep(5);
    print "And we're done".PHP_EOL;
});

我的印象是协程中的命令会像在一个单独的线程中执行,我的意思是线程不会关心父脚本线程中发生的事情,因为它在做自己的事情。

似乎并非如此。在发送消息之前,脚本会继续执行,直到我们完成下面的“任务”,消息才最终被发送。我期待的顺序如下:

About to send message [Ping] to recipients [75371]
Finally the message was sent
But wait, I'm gonna be busy with other tasks for 5 seconds first
Gonna be busy again again for another 5 seconds
And we're done

但我得到的顺序如下:

About to send message [Ping] to recipients [75371]
But wait, I'm gonna be busy with other tasks for 5 seconds first
Gonna be busy again again for another 5 seconds
Finally the message was sent
And we're done

我对协程有什么误解?我已经将协程作为一个实际的独立 PHP 线程来执行。然后它起作用了,但这似乎有点适得其反,因为我认为协程 是 线程。 所有东西都必须在协程中才能工作吗?

【问题讨论】:

    标签: php websocket swoole


    【解决方案1】:

    这是正确的输出

    About to send message [Ping] to recipients [75371]
    But wait, I'm gonna be busy with other tasks for 5 seconds first
    Finally the message was sent
    Gonna be busy again again for another 5 seconds
    And we're done
    

    这里生成了一个IO,导致协程切换。

    $client = new \Swoole\Coroutine\Http\Client(0.0.0.0, 1234);
    

    所以,去But wait, I'm gonna be busy with other tasks for 5 seconds first

    获取sleep,再次切换到上面的客户端

    【讨论】:

    • 切换是什么意思?有办法解决吗?
    • 对不起,我的表达可能有些问题。 switch的含义可以理解为:协程调度。你可以看到swoole.co.uk/article/…
    猜你喜欢
    • 2016-05-09
    • 1970-01-01
    • 1970-01-01
    • 2015-04-12
    • 2022-10-07
    • 2018-03-31
    • 1970-01-01
    • 2019-08-25
    • 2021-09-09
    相关资源
    最近更新 更多