Thinkphp workerman gatewayWorker 不能在windows 下启动
提示:
GatewayWorker Not Support On Windows.
解决方案:
自定义命令行
代码如下
namespace app\command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\facade\Config;
use think\worker\command\GatewayWorker;
use Workerman\Worker;
/**
* GatewayWorker win环境下的启动
*
* Class GatewayWorkerWin
* @package app\command
*/
class GatewayWorkerForWin extends GatewayWorker
{
public function configure()
{
$this->setName('worker:gateway_win')
->addArgument('service', Argument::OPTIONAL, 'workerman service: gateway|register|business_worker', null)
->addOption('host', 'H', Option::VALUE_OPTIONAL, 'the host of workerman server.', null)
->addOption('port', 'p', Option::VALUE_OPTIONAL, 'the port of workerman server.', null)
->setDescription('GatewayWorker Server for ThinkPHP runs on Windows system');
}
/**
* 由于windows下不支持下无法使用status、stop、reload、restart等命令。
* 所以去掉status、stop、reload、restart、守护进程等命令。
* 文档说明: https://www.workerman.net/doc/workerman/must-read.html
*
* 命令使用:
* php think worker:gateway_win register
* php think worker:gateway_win business_worker
* php think worker:gateway_win gateway
*
* @param Input $input
* @param Output $output
* @return int|void|null
*/
public function execute(Input $input, Output $output)
{
$service = $input->getArgument('service');
$option = Config::get('gateway_worker');
if ($input->hasOption('host')) {
$host = $input->getOption('host');
} else {
$host = !empty($option['host']) ? $option['host'] : '0.0.0.0';
}
if ($input->hasOption('port')) {
$port = $input->getOption('port');
} else {
$port = !empty($option['port']) ? $option['port'] : '2347';
}
$registerAddress = !empty($option['registerAddress']) ? $option['registerAddress'] : '127.0.0.1:1236';
switch ($service) {
case 'register':
$this->register($registerAddress);
break;
case 'business_worker':
$this->businessWorker($registerAddress, isset($option['businessWorker']) ? $option['businessWorker'] : []);
break;
case 'gateway':
$this->gateway($registerAddress, $host, $port, $option);
break;
default:
$output->writeln("Invalid argument action:{$service}, Expected gateway|register|business_worker. ");
exit(1);
break;
}
Worker::runAll();
}
}
console.php 里面配置
[
'worker:gateway_win' => 'app\command\GatewayWorkerForWin',
],
];
命令行分三次运行
php think worker:gateway_win register
php think worker:gateway_win business_worker
php think worker:gateway_win gateway
========== 解决方案看到这里就可以了,下面是分析与解释 =======================
根据workerman官方说明手册
发现windows下有如下限制
查看源码
namespace think\worker\command
/**
* Worker 命令行类
*/
class GatewayWorker extends Command
{
// 其他代码省略
/**
* 启动
* @access public
* @param string $host 监听地址
* @param integer $port 监听端口
* @param array $option 参数
* @return void
*/
public function start(string $host, int $port, array $option = [])
{
$registerAddress = !empty($option['registerAddress']) ? $option['registerAddress'] : '127.0.0.1:1236';
if (!empty($option['register_deploy'])) {
// 分布式部署的时候其它服务器可以关闭register服务
// 注意需要设置不同的lanIp
$this->register($registerAddress);
}
// 启动businessWorker
if (!empty($option['businessWorker_deploy'])) {
$this->businessWorker($registerAddress, $option['businessWorker'] ?? []);
}
// 启动gateway
if (!empty($option['gateway_deploy'])) {
$this->gateway($registerAddress, $host, $port, $option);
}
Worker::runAll();
}
}
一个文件里面初始化多个监听
导致thinkphp源码中直接做了判断,在window环境下,不可使用gatewayWorker