简体   繁体   English

PHP Swoole 协程,异步消息不异步

[英]PHP Swoole coroutine, async messages not async

I am running a Swoole WebSocket server and I am trying to send messages to end users while a script is running.我正在运行 Swoole WebSocket 服务器,并且尝试在脚本运行时向最终用户发送消息。 The problem I am having is that the messages aren't sent asynchronously, and are only sent once the script finishes execution.我遇到的问题是消息不是异步发送的,只有在脚本完成执行后才会发送。 Which sort of defeats the purpose.哪种方式违背了目的。

A condensed version of my issue is as follows:我的问题的精简版如下:

# 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;
});

I was under the impression that the commands in the coroutine would be executed like a separate thread, by that I mean that the thread wouldn't care what is happening in the parent script thread, because it's doing it's own thing.我的印象是协程中的命令将单独的线程一样执行,我的意思是线程不会关心父脚本线程中发生的事情,因为它正在做自己的事情。

That doesn't seem to be the case.情况似乎并非如此。 Before the message gets sent, the script continues and it's not until we're done with the "tasks" below that the message finally gets sent.在发送消息之前,脚本会继续执行,直到我们完成下面的“任务”,消息才最终被发送。 The order I was expecting was as follows:我期待的顺序如下:

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

But the order I am getting is as follows:但我得到的顺序如下:

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

What am I getting wrong about coroutines?我对协程有什么误解? I have resorted to executing the coroutine as an actual separate PHP thread.我已经将协程作为一个实际单独的 PHP 线程执行。 Then it works, but that seems to be slightly counterproductive, as I thought coroutines were the thread.然后它起作用了,但这似乎有点适得其反,因为我认为协程线程。 Does everything have to be in a coroutine for it to work?一切都必须在协程中才能工作吗?

This is the correct output这是正确的 output

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

Here an IO is generated that causes the coroutine to switch.这里生成了一个 IO 导致协程切换。

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

so, go to But wait, I'm gonna be busy with other tasks for 5 seconds first所以,go 到But wait, I'm gonna be busy with other tasks for 5 seconds first

get sleep , switch again to the client above sleep ,再次切换到上面的客户端

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM