用的是workerman框架,我自定义了一个Server类(继承自Worker), 但是运行起来后,onWorkerStart和onMessage都没问题,但是用php start.php reload,脚本就卡住了,后来一检查,发现似乎是php start.php start跑完后,有进程没跑完!因为当我按Ctrl+C停止进程后,能进入处理reload的地方了,所以不知道问题在哪里,能帮忙看下吗,感激不尽。
start_xxx.php:
<?php
/**
* Created by PhpStorm.
* User: zcm
* Mail: zhouciming@163.com
* Date: 2018/10/10 下午2:16
*/
use Workerman\Worker;
use Common\Config;
use Common\MyDb;
use think\Db;
use Server\Server;
require_once __DIR__ . '/../../vendor/autoload.php';
require_once __DIR__ . '/../autoload.php';
//
//$config = Config::get('server.global');
//print_r($config);
$worker = new Server("tcp://0.0.0.0:2345");
// 4 processes
$worker->count = 1;
// Emitted when data received
//$worker->onMessage = function($connection, $data)
//{
// echo "in callback onMessage\n";
// print_r($data);
// $connection->send("hello world2256 \n");
//};
////
//$worker->onWorkerStart = function($worker)
//{
// if(MyDb::init())
// {
// $rows = Db::name('users')
// ->field('id,user_nicename')
// ->where('id=239851')
// ->select();
//
// print_r($rows);
//
// $a = MyDb::$redis->get('hello');
// print_r($a);
// }
//};
// run all workers
if(!defined('GLOBAL_START'))
{
Worker::runAll();
}
Server\Server.php
<?php
/**
* Created by PhpStorm.
* User: zcm
* Mail: zhouciming@163.com
* Date: 2018/10/11 上午9:50
*/
//namespace Center\Server;
namespace Server;
use Workerman\Worker;
class Server extends Worker
{
/**
* 保存用户设置的 workerStart 回调
*
* @var callback
*/
protected $_onWorkerStart = null;
/**
* 保存用户设置的 workerReload 回调
*
* @var callback
*/
protected $_onWorkerReload = null;
/**
* 保存用户设置的 workerStop 回调
*
* @var callback
*/
protected $_onWorkerStop= null;
/**
* 保存用户设置的 onMessage 回调
*
* @var callback
*/
protected $_onMessage= null;
public function __construct($socket_name = '', array $context_option = array())
{
parent::__construct($socket_name, $context_option);
$backrace = debug_backtrace();
$this->_autoloadRootPath = dirname($backrace);
}
public function run()
{
// 保存用户设置的回调函数
$this->_onWorkerStart = $this->onWorkerStart;
$this->_onWorkerReload = $this->onWorkerReload;
$this->_onWorkerStop = $this->onWorkerStop;
$this->_onMessage = $this->onMessage;
// 设置本类的接口
$this->onWorkerStart = array($this, 'onWorkerStart');
$this->onWorkerReload = array($this, 'onWorkerReload');
$this->onWorkerStop = array($this, 'onWorkerStop');
$this->onMessage = array($this, 'onMessage');
parent::run();
}
/**
* 当进程启动时一些初始化工作
*
* @return void
*/
public function onWorkerStart()
{
echo "in Server::onWorkerStart\n";
if ($this->_onWorkerStart) {
call_user_func($this->_onWorkerStart, $this);
}
}
public function onWorkerStop()
{
echo "in Server::onWorkerStop\n";
if ($this->_onWorkerStop) {
call_user_func($this->_onWorkerStop, $this);
}
}
public function onWorkerReload($worker)
{
echo "in Server::onWorkerReload\n";
// if ($this->_onWorkerReload) {
// call_user_func($this->_onWorkerReload, $this);
// }
// 防止进程立刻退出
$worker->reloadable = false;
// 延迟 0.05 秒退出,避免 BusinessWorker 瞬间全部退出导致没有可用的 BusinessWorker 进程
Timer::add(0.05, array('Workerman\Worker', 'stopAll'));
// 执行用户定义的 onWorkerReload 回调
if ($this->_onWorkerReload) {
call_user_func($this->_onWorkerReload, $this);
}
}
public function onMessage($connection, $data)
{
echo "in Server::onMessage\n";
print_r($data);
if ($this->_onMessage) {
call_user_func($this->_onMessage, $connection, $data);
}
}
}
Server.php参考Gateway类改的!
我经过断点调试,已经跑完了Worker::run(),static::$globalEvent->loop();
这句话也跑了!然后我就知道去哪里了,应该是进入正常的事件循环吧,可是为何reload无法得到处理呢?还请大神解答下, Thank you!
不要继承Worker,因为有可能改变了它的某些行为导致不可预知的结果。
你可以在Worker的继承上包装一层,而不是继承它
你是指自己写个类,弄个成员变量是Worker,然后再使用!?
但是我看你的Gateway也是继承自Worker,而且是ok的!
另外,我看了自己5年前的代码(Workerman版本3.2.2),也是自定义了一个类,继承自Worker,使用完全没问题,用reload也是完全正常的,你可以帮我跑下那个Server吗,试试为什么start后似乎没跑完,卡在哪了?万分感激!
发一个完整的压缩包上来吧
我在给您整理压缩包时,又试了下reload,发现并不是没用,而是我的phpstorm开启了调试,卡在断点那了,我观察不够仔细,抱歉!
去除断点后,已经可以正常处理reload, stop等了!
好吧
@1:楼下的问题,请帮忙看下,谢谢
想请问下,我这里添加的这几个接口实现会改变worker的原始行为吗?请帮忙检查下,特别是onWorkerReload的实现,那样写合理吗,我是参考gatewayworker中BusinessWorker的实现写的!如果没什么问题,我将会在这个框架上增加代码!