Siam博客

hyperf命令行与协程

2022-12-10

hyperf命令行与协程

背景

需要自定义命令行Command 启动附属的Server服务

记录一下引发的几个问题

无法启动

产生报错

Swoole\Server::start(): eventLoop has already been created, unable to start Swoole\Server

原因:Command中已经开启了协程无法再监听server

Co::create(function(){
    $server = new Server('0.0.0.0', 9501, SWOOLE_BASE, SWOOLE_SOCK_TCP);
    $server->start();
});

处理方案,在Command类中定义属性,关闭协程

class StartCommand extends HyperfCommand
{

    /**
     * Execution in a coroutine environment.
     */
    protected $coroutine = false;

    // .....

}

关闭协程后的问题

查看hyperf-command组件代码 核心如下

if ($this->coroutine && ! Coroutine::inCoroutine()) {
    run($callback, $this->hookFlags);
    return $this->exitCode;
}

return $callback();

开启了协程之后会传递hookFlags参数

在关闭协程之后 一些心跳函数里我写了如下代码

Coroutine::create(function(){
    while(true){
        // foreach send 
        \Hyperf\Utils\Coroutine::sleep(3);
    }
});

但是由于默认没有hook了,而Hyperf utils中使用的不是Swoole提供的sleep函数,所以会造成进程堵塞。导致其他逻辑无法运行。

解决方案:在server set里设置hook


$server->set([
    'worker_num' => 2,
    'daemonize' => $daemon,
    'enable_coroutine' => true,
    'hook_flags' => swoole_hook_flags(),
]);
本文链接:
版权声明: 本文由 Siam原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权
Tags: SWOOLE

扫描二维码,分享此文章