SW-X生命周期的概念,是指框架核心在处理业务时,某些场景下会触发相应的回调事件转发。
生命周期回调方法统一存放在:/box/lifecycle/
目录下,统一使用run()
方法作为回调入口。
现框架共支持16
种场景下的生命周期回调处理。
地址:/box/lifecycle/worker_start
作用:可用于一些服务重启时的初始化操作,比如重置某些配置项,清除Reids缓存等操作。
默认代码:
namespace box\lifecycle;
class worker_start
{
/**
* 接受回调处理
* @todo 无
* @author 小黄牛
* @version v1.1.4 + 2020.07.12
* @deprecated 暂不启用
* @global 无
* @return bool
*/
public function run() {
// 这里可以做些业务重新初始化的工作
return true;
}
}
地址:/box/lifecycle/mysql_pop_error
作用:由于框架的Mysql组件是使用连接池的实现方式,如果业务代码中随意造成致命异常,框架有可能会造成无法自动回收连接数,所以当Mysql可用连接池降到0
时,会触发该周期回调,可做一些自动短信通知等操作。
默认代码:
namespace box\lifecycle;
class mysql_pop_error
{
/**
* 接受回调处理
* @todo 无
* @author 小黄牛
* @version v1.1.5 + 2020.07.15
* @deprecated 暂不启用
* @global 无
* @param string $type 连接池类型
* @return bool
*/
public function run($type) {
// 此处可自行实现消息通知
echo $type.' Mysql 连接数不足!'.PHP_EOL;
return true;
}
}
地址:/box/lifecycle/redis_pop_error
作用:由于框架的Redis组件是使用连接池的实现方式,如果业务代码中随意造成致命异常,框架有可能会造成无法自动回收连接数,所以当Redis可用连接池降0
时,会触发该周期回调,可做一些自动短信通知等操作。
默认代码:
namespace box\lifecycle;
class redis_pop_error
{
/**
* 接受回调处理
* @todo 无
* @author 小黄牛
* @version v1.1.5 + 2020.07.15
* @deprecated 暂不启用
* @global 无
* @param string $type 连接池类型
* @return bool
*/
public function run($type) {
// 此处可自行实现消息通知
echo $type.' Redis 连接数不足!'.PHP_EOL;
return true;
}
}
地址:/box/lifecycle/route_start
作用:当注解扫描完成时,会回调该生命周期,开发者可以基于回调内容进行相应的HTML文档生成或者记录。
默认代码:
namespace box\lifecycle;
class route_start
{
/**
* 接受回调处理
* @todo 无
* @author 小黄牛
* @version v1.1.5 + 2020.07.15
* @deprecated 暂不启用
* @global 无
* @param array $list 整张路由表
* @return bool
*/
public function run($list) {
return true;
}
}
地址:/box/lifecycle/controller_error
作用:当应用层捕捉到错误时,框架会回调该生命周期进行错误输出。
注意:该事件暂时只对HTTP
、WebSocket
服务有效。
默认代码:
namespace box\lifecycle;
class controller_error
{
/**
* 接受回调处理
* @todo 无
* @author 小黄牛
* @version v1.1.5 + 2020.07.15
* @deprecated 暂不启用
* @global 无
* @param array $e 错误内容
* @param string $error 系统自定义错误描述
* @param array $source 错误上下文内容
* @return bool
*/
public function run($e, $error, $source) {
$type = \x\Config::get('server.sw_service_type');
// HTTP请求
if ($type == 'http') {
$obj = $this->http($e, $error, $source);
// websocket请求
} else if($type == 'websocket') {
if (\x\context\Container::get('websocket_frame')) {
$obj = new \x\controller\WebSocket();
$obj->fetch('controller_error', 'error', $error);
} else {
$obj = $this->http($e, $error, $source);
}
// Rpc请求
} else if($type == 'rpc') {
$ServerCurrency = new \x\rpc\ServerCurrency();
$ServerCurrency->returnJson(
\x\context\Container::get('server'),
\x\context\Container::get('fd'),
'200',
'controller_error',
$error
);
// MQTT请求
} else if($type == 'mqtt') {
$server = \x\context\Container::get('server');
$fd = \x\context\Container::get('fd');
$data = [
'type' => \x\mqtt\common\Types::DISCONNECT,
'msg' => $error,
];
if (\x\Config::get('mqtt.protocol_level') == 5) {
$server->send($fd, \x\mqtt\v5\Dc::pack($data));
} else {
$server->send($fd, \x\mqtt\v3\Dc::pack($data));
}
}
return true;
}
/**
* HTTP服务的错误界面
* @todo 无
* @author 小黄牛
* @version v2.5.5 + 2021-09-08
* @deprecated 暂不启用
* @global 无
* @return void
*/
private function http($e, $error, $source) {
// 开启调试模式则记录错误日志
if (\x\Config::get('app.de_bug') == true) {
# 引入详细报错页面
$exceptionFile = EXAMPLES_PATH.'tpl/error_test.php';
} else {
# 引入简单报错页面
$exceptionFile = EXAMPLES_PATH.'tpl/error_formal.php';
}
// 引入文件
ob_start();
include $exceptionFile;
$html = ob_get_clean();
$obj = new \x\controller\Http();
$obj->fetch($html);
unset($obj);
}
}
地址:/box/lifecycle/websocket_push_error
作用:当WebSocket服务底层调用Swoole的push()
方法抛出内容失败时,框架会触发该生命周期进行处理,开发者可以把需要抛出的内容使用消息队列记录起来,再结合定时任务重新抛出。
默认代码:
namespace box\lifecycle;
class websocket_push_error
{
/**
* 接受回调处理
* @todo 无
* @author 小黄牛
* @version v1.2.5 + 2020.07.21
* @deprecated 暂不启用
* @global 无
* @param Server $server 实例
* @param json $content push的内容
* @param int $fd 客户端标识
* @return bool
*/
public function run($server, $content, $fd) {
// 可以自己处理重新push逻辑
// $server->push($fd, $content);
return true;
}
}
地址:/box/lifecycle/rpc_error
作用:当RpcClient组件调用微服务失败时,回调该生命周期处理。
默认代码:
namespace box\lifecycle;
class rpc_error
{
/**
* 接受回调处理
* @todo 无
* @author 小黄牛
* @version v1.1.5 + 2020.07.15
* @deprecated 暂不启用
* @global 无
* @param string $class 请求地址
* @param string $function 请求方法
* @param array $config 错误的微服务配置
* @param int $status 错误类型
* 1.ping的linux指令不能正常使用
* 2.ping不通
* @return bool
*/
public function run($class, $function, $config, $status) {
// 此处可自行实现消息通知
echo '微服务:'.$class.' '.$function.' 错误,事件编号:'.$status.PHP_EOL;
return true;
}
}
地址:/box/lifecycle/testcase_callback
作用:当我们在CMD命令行中启动某个单元测试用例时,若该单元测试不通过时,会触发该回调事件。
注意:该事件暂时只对HTTP
、WebSocket
服务有效。
默认代码:
namespace box\lifecycle;
class testcase_callback
{
/**
* 接受回调处理
* @todo 无
* @author 小黄牛
* @version v1.1.5 + 2020.07.15
* @deprecated 暂不启用
* @global 无
* @param string $tips 不通过的描述内容
* @return bool
*/
public function run($tips) {
$type = \x\Config::get('server.sw_service_type');
// HTTP请求
if ($type == 'http') {
$obj = new \x\controller\Http();
$obj->fetch($tips);
// websocket请求
} else if($type == 'websocket') {
$obj = new \x\controller\WebSocket();
$obj->fetch('route_error', 'error', $tips);
}
unset($obj);
return true;
}
}
地址:/box/lifecycle/annotate_param
作用:当@Param
注解校验不通过时,框架会回调该生命周期进行处理。
注意:该事件暂时只对HTTP
、WebSocket
服务有效。
默认代码:
namespace box\lifecycle;
class annotate_param
{
/**
* 接受回调处理
* @todo 无
* @author 小黄牛
* @version v1.1.4 + 2020.07.12
* @deprecated 暂不启用
* @global 无
* @param Swoole $server 服务实例
* @param string $fd 客户端标识
* @param string $tips 自定义提示内容
* @param string $name 参数名称
* @param string $status 错误事件状态码
* @param string $attach 错误检测返回附加说明
* @return bool
*/
public function run($server, $fd, $tips, $name, $status, $attach) {
if (!$tips) {
$tips = 'Annotate:Param filter Error,Name:'.$name.' ,SW-X Status:'.$status;
if ($attach) {
$tips .= ', Attach:'.$attach;
}
}
$type = \x\Config::get('server.sw_service_type');
// HTTP请求
if ($type == 'http') {
$obj = new \x\controller\Http();
$obj->fetch($tips);
// websocket请求
} else if($type == 'websocket') {
if (\x\context\Container::get('websocket_frame')) {
$obj = new \x\controller\WebSocket();
$obj->fetch('annotate_param_error', 'error', $tips);
} else {
$obj = new \x\controller\Http();
$obj->fetch($tips);
}
// Rpc请求
} else if($type == 'rpc') {
$ServerCurrency = new \x\rpc\ServerCurrency();
$ServerCurrency->returnJson($server, $fd, '200', 'annotate_param_error', $tips);
// MQTT请求
} else if($type == 'mqtt') {
$data = [
'type' => \x\mqtt\common\Types::DISCONNECT,
'msg' => $tips,
];
if (\x\Config::get('mqtt.protocol_level') == 5) {
$server->send($fd, \x\mqtt\v5\Dc::pack($data));
} else {
$server->send($fd, \x\mqtt\v3\Dc::pack($data));
}
}
return true;
}
}
地址:/box/lifecycle/csrf_error
作用:当@Csrf
注解校验失败时,框架会回调该生命周期进行处理。
注意:该事件暂时只对HTTP
服务有效。
默认代码:
namespace box\lifecycle;
class csrf_error
{
/**
* 接受回调处理
* @todo 无
* @author 小黄牛
* @version v1.1.5 + 2020.07.15
* @deprecated 暂不启用
* @global 无
* @param string $tips 错误内容
* @return bool
*/
public function run($tips) {
$obj = new \x\controller\Http();
$obj->fetch($tips);
return true;
}
}
地址:/box/lifecycle/jwt_error
作用:当@Jwt
注解校验失败时,框架会回调该生命周期进行处理。
注意:该事件暂时只对HTTP
服务有效。
默认代码:
namespace box\lifecycle;
class jwt_error
{
/**
* 接受回调处理
* @todo 无
* @author 小黄牛
* @version v1.1.5 + 2020.07.15
* @deprecated 暂不启用
* @global 无
* @param string $tips 错误内容
* @return bool
*/
public function run($tips) {
$obj = new \x\controller\Http();
$obj->fetch($tips);
return true;
}
}
地址:/box/lifecycle/route_error
作用:当除了@Param
、@Csrf
、@Jwt
以外的注解校验失败时,框架会回调该生命周期进行处理。
注意:该事件暂时只对HTTP
、WebSocket
服务有效。
默认代码:
namespace box\lifecycle;
class route_error
{
/**
* 接受回调处理
* @todo 无
* @author 小黄牛
* @version v1.1.5 + 2020.07.15
* @deprecated 暂不启用
* @global 无
* @param Swoole $server 服务实例
* @param string $fd 客户端标识
* @param string $status 错误事件状态码
* @return bool
*/
public function run($server, $fd, $status) {
$tips = 'Annotate:SW-X Status:'.$status.' ERROR !';
$type = \x\Config::get('server.sw_service_type');
// HTTP请求
if ($type == 'http') {
$obj = new \x\controller\Http();
$obj->fetch($tips);
// websocket请求
} else if($type == 'websocket') {
if (\x\context\Container::get('websocket_frame')) {
$obj = new \x\controller\WebSocket();
$obj->fetch('route_error', 'error', $tips);
} else {
$obj = new \x\controller\Http();
$obj->fetch($tips);
}
// Rpc请求
} else if($type == 'rpc') {
$ServerCurrency = new \x\rpc\ServerCurrency();
$ServerCurrency->returnJson($server, $fd, '200', 'route_error', $tips);
// MQTT请求
} else if($type == 'mqtt') {
$data = [
'type' => \x\mqtt\common\Types::DISCONNECT,
'msg' => $tips,
];
if (\x\Config::get('mqtt.protocol_level') == 5) {
$server->send($fd, \x\mqtt\v5\Dc::pack($data));
} else {
$server->send($fd, \x\mqtt\v3\Dc::pack($data));
}
}
return true;
}
}
地址:/box/lifecycle/swoole_table_start
版本:2.5.4
版本起支持
作用:当服务重启时,可以在这里,进行一些内存表的数据初始化渲染操作
默认代码:
namespace box\lifecycle;
class swoole_table_start
{
/**
* 接受回调处理
* @todo 无
* @author 小黄牛
* @version v1.1.5 + 2020.07.15
* @deprecated 暂不启用
* @global 无
* @param string $table 表名
* @param array $field 字段列表
* @param bool $status 状态 true.创建成功 false.创建失败
* @return bool
*/
public function run($table, $field, $status) {
// 当服务重启时,可以在这里,进行一些内存表的数据初始化渲染操作
return true;
}
}
地址:/box/lifecycle/limit_route_check
版本:2.5.5
版本起支持
服务支持:http
、websocket
、rpc
作用:当路由限流器达到峰值时,可以在这里,进行一些自定义的客户端回调通知操作,或者直接close()
掉server
服务。
默认代码:
namespace box\lifecycle;
class limit_route_check
{
/**
* 接受回调处理
* @todo 无
* @author 小黄牛
* @version v2.5.5 + 2021-09-06
* @deprecated 暂不启用
* @global 无
* @param Swoole $server 服务实例
* @param string $fd 客户端标识
* @param string $server_type 服务类型 http/websocket/rpc
* @param string $route 触发路由
* @param string $data 对应限流配置信息
* @return void
*/
public function run($server, $fd, $server_type, $route, $data) {
$msg = $route.' 已被限制,'.$data['time'].'s 内,只允许访问'.$data['peak'].'次!';
switch ($server_type) {
case 'http':
$obj = new \x\controller\Http();
$obj->fetch($msg);
break;
case 'websocket':
$obj = new \x\controller\WebSocket();
$obj->fetch('limit_error', 'error', $msg);
break;
case 'rpc':
$ServerCurrency = new \x\rpc\ServerCurrency();
$ServerCurrency->returnJson($server, $fd, '200', 'RPC Route LIMIT', $msg);
break;
}
return true;
}
}
地址:/box/lifecycle/limit_ip_check
版本:2.5.5
版本起支持
服务支持:http
、websocket
、rpc
、mqtt
作用:当IP限流器达到峰值时,可以在这里,进行一些自定义的客户端回调通知操作,或者直接close()
掉server
服务。
默认代码:
namespace box\lifecycle;
class limit_ip_check
{
/**
* 接受回调处理
* @todo 无
* @author 小黄牛
* @version v2.5.5 + 2021-09-06
* @deprecated 暂不启用
* @global 无
* @param Swoole $server 服务实例
* @param string $fd 客户端标识
* @param string $server_type 服务类型 http/websocket/rpc/mqtt
* @param string $ip 触发IP
* @param string $data 对应限流配置信息
* @return void
*/
public function run($server, $fd, $server_type, $ip, $data) {
$msg = $ip.' 已被限制,'.$data['time'].'s 内,只允许访问'.$data['peak'].'次!';
switch ($server_type) {
case 'http':
$obj = new \x\controller\Http();
$obj->fetch($msg);
break;
case 'websocket':
$obj = new \x\controller\WebSocket();
$obj->fetch('limit_error', 'error', $msg);
break;
case 'rpc':
$ServerCurrency = new \x\rpc\ServerCurrency();
$ServerCurrency->returnJson($server, $fd, '200', 'RPC Ip LIMIT', $msg);
break;
case 'mqtt':
$data = [
'type' => \x\mqtt\common\Types::DISCONNECT,
'msg' => $msg,
];
if (\x\Config::get('mqtt.protocol_level') == 5) {
$server->send($fd, \x\mqtt\v5\Dc::pack($data));
} else {
$server->send($fd, \x\mqtt\v3\Dc::pack($data));
}
$server->close($fd);
break;
}
return true;
}
}
地址:/box/lifecycle/validate_error
版本:2.5.6
版本起支持
服务支持:http
、websocket
、rpc
、mqtt
作用:当Validate验证器注解检测失败时,默认会回调到该生命周期进行处理。
默认代码:
namespace box\lifecycle;
class validate_error
{
/**
* 接受回调处理
* @todo 无
* @author 小黄牛
* @version v2.5.6 + 2021-09-15
* @deprecated 暂不启用
* @global 无
* @param string $server_type 服务类型 http/websocket/rpc/mqtt
* @param bool $batch 是否全部过滤
* @param array $errors 错误验证结果集
* @return bool
*/
public function run($server_type, $batch, $errors) {
// $batch 是用于执行全部过滤规则,再最后一起返回全部的错误原因
// 默认生命周期只返回第一个错误原因
$error = $errors[0]['intact_field'].' => '.$errors[0]['message'];
// HTTP请求
if ($server_type == 'http') {
$obj = new \x\controller\Http();
$obj->fetch($error);
// websocket请求
} else if($type == 'websocket') {
$obj = new \x\controller\WebSocket();
$obj->fetch('controller_error', 'error', $error);
// Rpc请求
} else if($server_type == 'rpc') {
$ServerCurrency = new \x\rpc\ServerCurrency();
$ServerCurrency->returnJson(
\x\context\Container::get('server'),
\x\context\Container::get('fd'),
'200',
'controller_error',
$error
);
// MQTT请求
} else if($server_type == 'mqtt') {
$server = \x\context\Container::get('server');
$fd = \x\context\Container::get('fd');
$data = [
'type' => \x\mqtt\common\Types::DISCONNECT,
'msg' => $error,
];
$arr = $server->fds[$fd];
$class = $arr['class'];
$server->send($fd, $class::pack($data));
}
return true;
}
}