add Middleware and release version 1.1.0

This commit is contained in:
whale 2020-03-29 16:29:02 +08:00
parent c2fcdf9668
commit 9a28126765
11 changed files with 175 additions and 21 deletions

View File

@ -51,6 +51,7 @@ class ZMBuf
public static $atomics;
public static $req_mapping = [];
public static $config = [];
public static $context = [];
static function get($name, $default = null) {
return self::$cache[$name] ?? $default;

View File

@ -1,5 +1,8 @@
<?php
use Framework\ZMBuf;
use ZM\Utils\Context;
function classLoader($p) {
$filepath = getClassPath($p);
if ($filepath === null)
@ -144,3 +147,19 @@ function matchArgs($pattern, $context) {
return $result;
} else return false;
}
function set_coroutine_params($array){
$cid = Co::getCid();
if($cid == -1) die("Cannot set coroutine params at none coroutine mode.");
ZMBuf::$context[$cid] = $array;
foreach(ZMBuf::$context as $c => $v) {
if(!Co::exists($c)) unset(ZMBuf::$context[$c]);
}
}
function context(){
$cid = Co::getCid();
if(isset(ZMBuf::$context[$cid])) {
return new Context(ZMBuf::$context[$cid], $cid);
} else return null;
}

View File

@ -6,6 +6,7 @@ namespace Module\Example;
use Framework\Console;
use ZM\Annotation\CQ\CQCommand;
use ZM\Annotation\Http\Middleware;
use ZM\Annotation\Http\RequestMapping;
use ZM\Annotation\Swoole\SwooleEventAt;
use ZM\Connection\CQConnection;
@ -33,6 +34,7 @@ class Hello extends ModBase
/**
* @RequestMapping("/test/ping")
* @Middleware("timer")
*/
public function pong(){
return "pong";

View File

@ -0,0 +1,38 @@
<?php
namespace Module\Middleware;
use Framework\Console;
use ZM\Annotation\Http\After;
use ZM\Annotation\Http\Before;
use ZM\Annotation\Http\MiddlewareClass;
use ZM\Http\MiddlewareInterface;
/**
* Class AuthMiddleware
* 示例中间件:用于统计路由函数运行时间用的
* @package Module\Middleware
* @MiddlewareClass()
*/
class TimerMiddleware implements MiddlewareInterface
{
private $starttime;
/**
* @Before()
* @return bool
*/
public function onBefore() {
$this->starttime = microtime(true);
return true;
}
/**
* @After()
*/
public function onAfter() {
Console::info("Using " . round((microtime(true) - $this->starttime) * 1000, 2) . " ms.");
}
public function getName() { return "timer"; }
}

View File

@ -5,6 +5,7 @@ namespace ZM\Annotation;
use Doctrine\Common\Annotations\AnnotationException;
use Doctrine\Common\Annotations\AnnotationReader;
use Framework\Console;
use Framework\ZMBuf;
use ReflectionClass;
use ReflectionException;
@ -61,24 +62,30 @@ class AnnotationParser
} elseif ($vs instanceof InitBuffer) {
ZMBuf::set($vs->buf_name, []);
} elseif ($vs instanceof MiddlewareClass) {
Console::info("正在注册中间件 ".$vs->class);
$result = [
"class" => "\\".$reflection_class->getName()
"class" => "\\" . $reflection_class->getName()
];
foreach ($methods as $vss) {
if ($vss->getName() == "getName") {
/** @var MiddlewareInterface $tmp */
$tmp = new $v();
$result["name"] = $tmp->getName();
continue;
}
$method_annotations = $reader->getMethodAnnotations($vss);
foreach ($method_annotations as $vsss) {
if ($vss instanceof Rule) $vss = self::registerRuleEvent($vsss, $vss, $reflection_class);
else $vss = self::registerMethod($vsss, $vss, $reflection_class);
echo get_class($vsss).PHP_EOL;
//echo get_class($vsss) . PHP_EOL;
if ($vsss instanceof Before) $result["before"] = $vsss->method;
if ($vsss instanceof After) $result["after"] = $vsss->method;
if ($vsss instanceof HandleException) {
$result["exception"] = $vsss->class_name;
$result["exception_method"] = $vsss->method;
$result["exceptions"][$vsss->class_name] = $vsss->method;
}
}
}
ZMBuf::$events[MiddlewareClass::class]["\\".$reflection_class->getName()] = $result;
ZMBuf::$events[MiddlewareClass::class][$result["name"]] = $result;
continue 2;
}
}
@ -100,7 +107,7 @@ class AnnotationParser
elseif ($vss instanceof CQBefore) ZMBuf::$events[CQBefore::class][$vss->cq_event][] = $vss;
elseif ($vss instanceof CQAfter) ZMBuf::$events[CQAfter::class][$vss->cq_event][] = $vss;
elseif ($vss instanceof OnStart) ZMBuf::$events[OnStart::class][] = $vss;
elseif ($vss instanceof Middleware){
elseif ($vss instanceof Middleware) {
ZMBuf::$events[MiddlewareInterface::class][$vss->class][$vss->method] = $vss->middleware;
}
}

View File

@ -5,6 +5,7 @@ namespace ZM\Event;
use Co;
use Error;
use Exception;
use Framework\Console;
use Framework\ZMBuf;
@ -28,6 +29,9 @@ class EventHandler
ZMUtil::stop();
return;
} catch(Error $e) {
var_export($e);
ZMUtil::stop();
}
break;
case "message":

View File

@ -5,6 +5,7 @@ namespace ZM\Event\Swoole;
use Closure;
use Doctrine\Common\Annotations\AnnotationException;
use Exception;
use Framework\ZMBuf;
use Swoole\Http\Request;
@ -87,10 +88,13 @@ class RequestEvent implements SwooleEvent
return $this;
}
set_coroutine_params(["request" => $this->request, "response" => $this->response, "params" => $params]);
if (in_array(strtoupper($this->request->server["request_method"]), $node["request_method"] ?? [])) { //判断目标方法在不在里面
$c_name = $node["class"];
if (isset(ZMBuf::$events[MiddlewareInterface::class][$c_name][$node["method"]])) {
$middleware = ZMBuf::$events[MiddlewareInterface::class][$c_name][$node["method"]];
if(!isset(ZMBuf::$events[MiddlewareClass::class][$middleware])) throw new AnnotationException("Annotation parse error: Unknown MiddlewareClass named \"{$middleware}\"!");
$middleware = ZMBuf::$events[MiddlewareClass::class][$middleware];
$before = $middleware["class"];
$r = new $before();
@ -107,11 +111,14 @@ class RequestEvent implements SwooleEvent
if (is_string($result) && !$this->response->isEnd()) $this->response->end($result);
if (!$this->response->isEnd()) goto eventCall;
} catch (Exception $e) {
if (!isset($middleware["exception"])) throw $e;
if ($e instanceof $middleware["exception"]) {
call_user_func([$r, $middleware["exception_method"]], $e, $this->request, $this->response, $params);
return $this;
} else throw $e;
if (!isset($middleware["exceptions"])) throw $e;
foreach($middleware["exceptions"] as $name => $method) {
if($e instanceof $name) {
call_user_func([$r, $method], $e, $this->request, $this->response, $params);
return $this;
}
}
throw $e;
}
}
if (isset($middleware["after"])) {

View File

@ -6,5 +6,5 @@ namespace ZM\Http;
interface MiddlewareInterface
{
public function getName();
}

View File

@ -157,6 +157,11 @@ class Response
public function isEnd() { return $this->is_end; }
public function endWithStatus($status_code = 200, $content = null){
$this->status($status_code);
$this->end($content);
}
/**
* @param $filename
* @param $offset

71
src/ZM/Utils/Context.php Normal file
View File

@ -0,0 +1,71 @@
<?php
namespace ZM\Utils;
use Swoole\Http\Request;
use Swoole\WebSocket\Frame;
use swoole_server;
use ZM\Http\Response;
class Context
{
private $server = null;
private $frame = null;
private $data = null;
private $request = null;
private $response = null;
private $cid;
public function __construct($param0, $cid) {
if (isset($param0["server"])) $this->server = $param0["server"];
if (isset($param0["frame"])) $this->frame = $param0["frame"];
if (isset($param0["data"])) $this->data = $param0["data"];
if (isset($param0["request"])) $this->request = $param0["request"];
if (isset($param0["response"])) $this->response = $param0["response"];
$this->cid = $cid;
}
/**
* @return swoole_server|null
*/
public function getServer() {
return $this->server;
}
/**
* @return Frame|null
*/
public function getFrame() {
return $this->frame;
}
/**
* @return array|null
*/
public function getData() {
return $this->data;
}
/**
* @return Request|null
*/
public function getRequest() {
return $this->request;
}
/**
* @return Response|null
*/
public function getResponse() {
return $this->response;
}
/**
* @return int|null
*/
public function getCid() {
return $this->cid;
}
}