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 $atomics;
public static $req_mapping = []; public static $req_mapping = [];
public static $config = []; public static $config = [];
public static $context = [];
static function get($name, $default = null) { static function get($name, $default = null) {
return self::$cache[$name] ?? $default; return self::$cache[$name] ?? $default;

View File

@@ -1,5 +1,8 @@
<?php <?php
use Framework\ZMBuf;
use ZM\Utils\Context;
function classLoader($p) { function classLoader($p) {
$filepath = getClassPath($p); $filepath = getClassPath($p);
if ($filepath === null) if ($filepath === null)
@@ -144,3 +147,19 @@ function matchArgs($pattern, $context) {
return $result; return $result;
} else return false; } 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 Framework\Console;
use ZM\Annotation\CQ\CQCommand; use ZM\Annotation\CQ\CQCommand;
use ZM\Annotation\Http\Middleware;
use ZM\Annotation\Http\RequestMapping; use ZM\Annotation\Http\RequestMapping;
use ZM\Annotation\Swoole\SwooleEventAt; use ZM\Annotation\Swoole\SwooleEventAt;
use ZM\Connection\CQConnection; use ZM\Connection\CQConnection;
@@ -33,6 +34,7 @@ class Hello extends ModBase
/** /**
* @RequestMapping("/test/ping") * @RequestMapping("/test/ping")
* @Middleware("timer")
*/ */
public function pong(){ public function pong(){
return "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\AnnotationException;
use Doctrine\Common\Annotations\AnnotationReader; use Doctrine\Common\Annotations\AnnotationReader;
use Framework\Console;
use Framework\ZMBuf; use Framework\ZMBuf;
use ReflectionClass; use ReflectionClass;
use ReflectionException; use ReflectionException;
@@ -61,24 +62,30 @@ class AnnotationParser
} elseif ($vs instanceof InitBuffer) { } elseif ($vs instanceof InitBuffer) {
ZMBuf::set($vs->buf_name, []); ZMBuf::set($vs->buf_name, []);
} elseif ($vs instanceof MiddlewareClass) { } elseif ($vs instanceof MiddlewareClass) {
Console::info("正在注册中间件 ".$vs->class);
$result = [ $result = [
"class" => "\\".$reflection_class->getName() "class" => "\\" . $reflection_class->getName()
]; ];
foreach ($methods as $vss) { foreach ($methods as $vss) {
if ($vss->getName() == "getName") {
/** @var MiddlewareInterface $tmp */
$tmp = new $v();
$result["name"] = $tmp->getName();
continue;
}
$method_annotations = $reader->getMethodAnnotations($vss); $method_annotations = $reader->getMethodAnnotations($vss);
foreach ($method_annotations as $vsss) { foreach ($method_annotations as $vsss) {
if ($vss instanceof Rule) $vss = self::registerRuleEvent($vsss, $vss, $reflection_class); if ($vss instanceof Rule) $vss = self::registerRuleEvent($vsss, $vss, $reflection_class);
else $vss = self::registerMethod($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 Before) $result["before"] = $vsss->method;
if ($vsss instanceof After) $result["after"] = $vsss->method; if ($vsss instanceof After) $result["after"] = $vsss->method;
if ($vsss instanceof HandleException) { if ($vsss instanceof HandleException) {
$result["exception"] = $vsss->class_name; $result["exceptions"][$vsss->class_name] = $vsss->method;
$result["exception_method"] = $vsss->method;
} }
} }
} }
ZMBuf::$events[MiddlewareClass::class]["\\".$reflection_class->getName()] = $result; ZMBuf::$events[MiddlewareClass::class][$result["name"]] = $result;
continue 2; continue 2;
} }
} }
@@ -100,7 +107,7 @@ class AnnotationParser
elseif ($vss instanceof CQBefore) ZMBuf::$events[CQBefore::class][$vss->cq_event][] = $vss; 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 CQAfter) ZMBuf::$events[CQAfter::class][$vss->cq_event][] = $vss;
elseif ($vss instanceof OnStart) ZMBuf::$events[OnStart::class][] = $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; ZMBuf::$events[MiddlewareInterface::class][$vss->class][$vss->method] = $vss->middleware;
} }
} }

View File

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

View File

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

View File

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

View File

@@ -157,6 +157,11 @@ class Response
public function isEnd() { return $this->is_end; } 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 $filename
* @param $offset * @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;
}
}