composer安装swoft后开启服务报错API must be called in coroutine
问题描述
使用 composesr
安装 swoft
后,开启服务报错:API must be called in coroutine
。
问题出现的环境背景及自己尝试过哪些方法
环境如下:
CentOS 6.8 PHP 7.3.1 swoole 4.4.0 swoft 2.0.3-beta
首先第一次安装swoft时,swoole版本为4.2,运行swoft时提示swoole版本过低,于是使用pecl更新了一下swoole,出现该错误。
这个错误我之前在测试swoole的demo时也碰到过,我猜想是swoft使用的老版本swoole语法导致。
但是转念一想需要4.3+才能使用,不应该出现此类问题,于是在代码中全局搜索“API must be called in coroutine”,并没有结果。
我猜想是swoole内置错误,swoft仅仅是输出错误。
于是追代码至SystemHelper.php文件中,如下片段
$descriptors = [
0 => ['pipe', 'r'], // stdin - read channel
1 => ['pipe', 'w'], // stdout - write channel
2 => ['pipe', 'w'], // stdout - error channel
3 => ['pipe', 'r'], // stdin - This is the pipe we can feed the password into
];
$pipes = [];
$process = proc_open($command, $descriptors, $pipes, $cwd); # $command = 'which php',$cwd = NULL。本行报错。
至此,猜想swoole内置保护,执行命令不允许阻塞,必须以协程形式吧。
相关代码
安装swoft代码
[mike@iZm5e24ws6xq5tw54e8vbnZ stone.dnfmiracle.xyz]$ composer create-project swoft/swoft swoft
启动swoft代码
[mike@iZm5e24ws6xq5tw54e8vbnZ stone.dnfmiracle.xyz]$ php bin/swoft http:start
详细报错如下:
[mike@iZm5e24ws6xq5tw54e8vbnZ stone.dnfmiracle.xyz]$ php bin/swoft http:start
2019/07/12-09:39:29 [INFO] Swoole\Runtime::enableCoroutine
2019/07/12-09:39:29 [INFO] Swoft\SwoftApplication:setSystemAlias(490) Set alias @base=/data/wwwroot/stone.dnfmiracle.xyz
2019/07/12-09:39:29 [INFO] Swoft\SwoftApplication:setSystemAlias(491) Set alias @app=@base/app
2019/07/12-09:39:29 [INFO] Swoft\SwoftApplication:setSystemAlias(492) Set alias @config=@base/config
2019/07/12-09:39:29 [INFO] Swoft\SwoftApplication:setSystemAlias(493) Set alias @runtime=@base/runtime
2019/07/12-09:39:29 [INFO] Project path is /data/wwwroot/stone.dnfmiracle.xyz
2019/07/12-09:39:29 [INFO] Swoft\Processor\EnvProcessor:handle(52) Env file(/data/wwwroot/stone.dnfmiracle.xyz/.env) is loaded
2019/07/12-09:39:29 [INFO] Swoft\Processor\AnnotationProcessor:handle(45) Annotations is scanned(autoloader 29, annotation 333, parser 64)
2019/07/12-09:39:29 [INFO] Swoft\Processor\BeanProcessor:handle(57) config path=/data/wwwroot/stone.dnfmiracle.xyz/config
2019/07/12-09:39:29 [INFO] Swoft\Processor\BeanProcessor:handle(58) config env=
2019/07/12-09:39:29 [INFO] Swoft\Processor\BeanProcessor:handle(62) Bean is initialized(singleton 232, prototype 63, definition 40)
2019/07/12-09:39:29 [INFO] Swoft\Processor\EventProcessor:handle(37) Event manager initialized(39 listener, 3 subscriber)
2019/07/12-09:39:29 [INFO] Swoft\WebSocket\Server\Listener\AppInitCompleteListener:handle(40) WebSocket server route registered(module 2, message command 3)
2019/07/12-09:39:29 [INFO] Swoft\Tcp\Server\Listener\AppInitCompleteListener:handle(42) Tcp server route registered(routes 0)
2019/07/12-09:39:29 [INFO] Swoft\Error\Listener\AppInitCompleteListener:handle(37) Error manager init completed(4 type, 5 handler, 5 exception)
2019/07/12-09:39:29 [INFO] Swoft\Processor\ConsoleProcessor:handle(39) Console command route registered (group 12, command 36)
Fatal error: Uncaught Swoole\Error: API must be called in the coroutine in /data/wwwroot/stone.dnfmiracle.xyz/vendor/swoft/stdlib/src/Helper/SystemHelper.php:72
Stack trace:
#0 /data/wwwroot/stone.dnfmiracle.xyz/vendor/swoft/stdlib/src/Helper/SystemHelper.php(72): proc_open('which php', Array, Array, NULL)
#1 /data/wwwroot/stone.dnfmiracle.xyz/vendor/swoft/server/src/Command/BaseServerCommand.php(44): Swoft\Stdlib\Helper\SystemHelper::run('which php')
#2 /data/wwwroot/stone.dnfmiracle.xyz/vendor/swoft/http-server/src/Command/HttpServerCommand.php(184): Swoft\Server\Command\BaseServerCommand->getFullCommand()
#3 /data/wwwroot/stone.dnfmiracle.xyz/vendor/swoft/http-server/src/Command/HttpServerCommand.php(47): Swoft\Http\Server\Command\HttpServerCommand->createServer()
#4 /data/wwwroot/stone.dnfmiracle.xyz/vendor/swoft/stdlib/src/Helper/PhpHelper.php(51): Swoft\Http\Server\Command\HttpServerCommand->start()
#5 /data/wwwroot/stone.dnfmiracle.xyz/vendor/swoft/console/src/ConsoleDispatcher.php(48): Swoft\Stdlib\Helper\PhpHelpe in /data/wwwroot/stone.dnfmiracle.xyz/vendor/swoft/stdlib/src/Helper/SystemHelper.php on line 72
Fatal error: Uncaught ErrorException: Uncaught Swoole\Error: API must be called in the coroutine in /data/wwwroot/stone.dnfmiracle.xyz/vendor/swoft/stdlib/src/Helper/SystemHelper.php:72
Stack trace:
#0 /data/wwwroot/stone.dnfmiracle.xyz/vendor/swoft/stdlib/src/Helper/SystemHelper.php(72): proc_open('which php', Array, Array, NULL)
#1 /data/wwwroot/stone.dnfmiracle.xyz/vendor/swoft/server/src/Command/BaseServerCommand.php(44): Swoft\Stdlib\Helper\SystemHelper::run('which php')
#2 /data/wwwroot/stone.dnfmiracle.xyz/vendor/swoft/http-server/src/Command/HttpServerCommand.php(184): Swoft\Server\Command\BaseServerCommand->getFullCommand()
#3 /data/wwwroot/stone.dnfmiracle.xyz/vendor/swoft/http-server/src/Command/HttpServerCommand.php(47): Swoft\Http\Server\Command\HttpServerCommand->createServer()
#4 /data/wwwroot/stone.dnfmiracle.xyz/vendor/swoft/stdlib/src/Helper/PhpHelper.php(51): Swoft\Http\Server\Command\HttpServerCommand->start()
#5 /data/wwwroot/stone.dnfmiracle.xyz/vendor/swoft/console/src/ConsoleDispatcher.php(48): Swo in /data/wwwroot/stone.dnfmiracle.xyz/vendor/swoft/stdlib/src/Helper/SystemHelper.php on line 72
问题点
(猜想)swoole禁止非协程形式执行命令,swoft启动服务器时以非协程形式执行命令,是因为我使用的swoft版本原因吗?还是大家都有这样的问题?
解决方案
将 swoole
版本回退至 4.3.5
,可以开启服务