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(),
]);
扫描二维码,分享此文章