用的是workerman框架,我自定義了一個(gè)Server類(繼承自Worker), 但是運(yùn)行起來(lái)后,onWorkerStart和onMessage都沒(méi)問(wèn)題,但是用php start.php reload,腳本就卡住了,后來(lái)一檢查,發(fā)現(xiàn)似乎是php start.php start跑完后,有進(jìn)程沒(méi)跑完!因?yàn)楫?dāng)我按Ctrl+C停止進(jìn)程后,能進(jìn)入處理reload的地方了,所以不知道問(wèn)題在哪里,能幫忙看下嗎,感激不盡。
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
{
/**
* 保存用戶設(shè)置的 workerStart 回調(diào)
*
* @var callback
*/
protected $_onWorkerStart = null;
/**
* 保存用戶設(shè)置的 workerReload 回調(diào)
*
* @var callback
*/
protected $_onWorkerReload = null;
/**
* 保存用戶設(shè)置的 workerStop 回調(diào)
*
* @var callback
*/
protected $_onWorkerStop= null;
/**
* 保存用戶設(shè)置的 onMessage 回調(diào)
*
* @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()
{
// 保存用戶設(shè)置的回調(diào)函數(shù)
$this->_onWorkerStart = $this->onWorkerStart;
$this->_onWorkerReload = $this->onWorkerReload;
$this->_onWorkerStop = $this->onWorkerStop;
$this->_onMessage = $this->onMessage;
// 設(shè)置本類的接口
$this->onWorkerStart = array($this, 'onWorkerStart');
$this->onWorkerReload = array($this, 'onWorkerReload');
$this->onWorkerStop = array($this, 'onWorkerStop');
$this->onMessage = array($this, 'onMessage');
parent::run();
}
/**
* 當(dāng)進(jìn)程啟動(dòng)時(shí)一些初始化工作
*
* @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);
// }
// 防止進(jìn)程立刻退出
$worker->reloadable = false;
// 延遲 0.05 秒退出,避免 BusinessWorker 瞬間全部退出導(dǎo)致沒(méi)有可用的 BusinessWorker 進(jìn)程
Timer::add(0.05, array('Workerman\Worker', 'stopAll'));
// 執(zhí)行用戶定義的 onWorkerReload 回調(diào)
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類改的!
?
我經(jīng)過(guò)斷點(diǎn)調(diào)試,已經(jīng)跑完了Worker::run(),static::$globalEvent->loop();
這句話也跑了!然后我就知道去哪里了,應(yīng)該是進(jìn)入正常的事件循環(huán)吧,可是為何reload無(wú)法得到處理呢?還請(qǐng)大神解答下, Thank you!
不要繼承Worker,因?yàn)橛锌赡芨淖兞怂哪承┬袨閷?dǎo)致不可預(yù)知的結(jié)果。
你可以在Worker的繼承上包裝一層,而不是繼承它
你是指自己寫個(gè)類,弄個(gè)成員變量是Worker,然后再使用???
但是我看你的Gateway也是繼承自Worker,而且是ok的!
另外,我看了自己5年前的代碼(Workerman版本3.2.2),也是自定義了一個(gè)類,繼承自Worker,使用完全沒(méi)問(wèn)題,用reload也是完全正常的,你可以幫我跑下那個(gè)Server嗎,試試為什么start后似乎沒(méi)跑完,卡在哪了?萬(wàn)分感激!
我在給您整理壓縮包時(shí),又試了下reload,發(fā)現(xiàn)并不是沒(méi)用,而是我的phpstorm開啟了調(diào)試,卡在斷點(diǎn)那了,我觀察不夠仔細(xì),抱歉!
去除斷點(diǎn)后,已經(jīng)可以正常處理reload, stop等了!
public function run()
{
// 保存用戶設(shè)置的回調(diào)函數(shù)
$this->_onWorkerStart = $this->onWorkerStart;
$this->_onWorkerReload = $this->onWorkerReload;
$this->_onWorkerStop = $this->onWorkerStop;
$this->_onMessage = $this->onMessage;
// 關(guān)聯(lián)基類成員至本類接口
$this->onWorkerStart = array($this, 'onWorkerStart');
$this->onWorkerReload = array($this, 'onWorkerReload');
$this->onWorkerStop = array($this, 'onWorkerStop');
$this->onMessage = array($this, 'onMessage');
parent::run();
}
/**
* 當(dāng)進(jìn)程啟動(dòng)時(shí)一些初始化工作
*
* @return void
*/
public function onWorkerStart()
{
echo "in Server::onWorkerStart22244\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" . $worker->reloadable . PHP_EOL;
// 防止進(jìn)程立刻退出
$worker->reloadable = false;
// 延遲 0.05 秒退出,避免 BusinessWorker 瞬間全部退出導(dǎo)致沒(méi)有可用的 BusinessWorker 進(jìn)程
Timer::add(0.05, array('Workerman\Worker', 'stopAll'));
// 執(zhí)行用戶定義的 onWorkerReload 回調(diào)
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);
}
}
想請(qǐng)問(wèn)下,我這里添加的這幾個(gè)接口實(shí)現(xiàn)會(huì)改變worker的原始行為嗎?請(qǐng)幫忙檢查下,特別是onWorkerReload的實(shí)現(xiàn),那樣寫合理嗎,我是參考gatewayworker中BusinessWorker的實(shí)現(xiàn)寫的!如果沒(méi)什么問(wèn)題,我將會(huì)在這個(gè)框架上增加代碼!