大家好,我是黄啊码,由于项目需要被迫无奈在老项目上整合workerman,整整浪费了我一天,按着tp官方文档去做,一个又一个的坑,然后百度网友的答案,又是一个又一个的天坑,真的无力吐槽,今天我就把自己的经历写在这里,网友们,别再踩坑了。
目录
composer require topthink/think-worker=2.0.*
这是官方文档给的,我照搬,一顿操作下来,没啥毛病,但是:由于官方对应的版本是比较老的,配置文件又是新的,导致以下位置找不到文件:
原因:官方为了避免Event和关键字Events冲突,直接将Event改成了Events,结果就是会导致Events::onMessage is not callable。
好了,这是天坑,先给大家指出来,咱们先做直接走起:
composer require topthink/think-worker=2.0.8
记住:是2.0.8,高也不要,低也不要,不然就会出现上边的问题,那你们就自己排查吧,欲哭无泪的那种。
一下是我compoers出来的workerman版本,仅供参考:
接下来开始启动吧:
think-worker默认有命令
php think worker:gateway
急急如律令,肯定是这个:
结果:丢,这是啥玩意儿:
GatewayWorker Not Support On Windows
这并不是说gateway不能再windows上运行,而是gateway需要启动好几个命令行,windows下无法直接处理,先做咱们就开始走起来吧
先自定义命令行文件:
<?php
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');
}
/**
* linux直接使用
* php think worker:gateway
* 由于windows下不支持下无法使用status、stop、reload、restart等命令。
* 所以去掉status、stop、reload、restart、守护进程等命令。
* 文档说明: https://www.workerman.net/doc/workerman/must-read.html
* windows系统下workerman单个进程仅支持200+个连接。
* windows系统下无法使用count参数设置多进程。
* windows系统下无法使用status、stop、reload、restart等命令。
* windows系统下无法守护进程,cmd窗口关掉后服务即停止。
* windows系统下无法在一个文件中初始化多个监听。
* linux系统无上面的限制,建议正式环境用linux系统,开发环境可以选择用windows系统。
*
* 命令使用:
* 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::pull('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("<error>Invalid argument action:{$service}, Expected gateway|register|business_worker.</error>");
exit(1);
break;
}
Worker::runAll();
}
}
位置在这里,别走错路了:
然后配置对应的命令行:改config/console.php文件,添加workerman命令
好了,到此配置结果,开动:
php think workerman register
php think workerman businessworker
php think workerman gateway
第一步:没问题:
第二步:没问题:
第三步:。。。。丢,这是啥玩意儿:
一步一步排查,排查到这里:
原来是GatewayWorker.php的option获取的东西是空的:
原来官方的代码是Config:get('gatewayworker'),而这里是:
到这里你应该觉得结束了,但是。。。运行还是报错,还是同样的错误,看来看去这代码没问题啊,难道是Config这个函数出错,输出了一下,果然是空的,不对,tp5的语法不是Config::get('文件名.变量名')吗?怎么这里是这样,我一度怀疑是官方文档更新了,查了文档
Config::set() 设置配置项
Config::get() 获取配置项
Config::pull() 仅仅只获取一级配置项
Config::has() 判断配置项是否存在
so》》》获取文件里边所有的配置项不是pull吗? 好了,直接改:
再次运行:php think workerman gateway
欲哭无泪啊,怎么会有如此低级的错误?来源:代码是抄网友的。。。
所以,如果你的tp框架是5.1+的,不建议你抄网文,因为天下文章一般抄,球球你们,别抄了,看我吧!!
好了,今天的分享就这里,有问题的留个言,别忘了一键三连,下次我们还会再见!
我是黄啊码,码字的码,退。。。退。。。退。。。朝!