add middleware arg trait and annotation trait

This commit is contained in:
crazywhalecc
2023-03-05 22:15:01 +08:00
committed by Jerry
parent b8501e94f0
commit 3e2911b807
7 changed files with 129 additions and 5 deletions

View File

@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace ZM\Middleware;
use OneBot\Util\Singleton;
use ZM\Annotation\AnnotationBase;
use ZM\Exception\InvalidArgumentException;
class MiddlewareHandler
@@ -71,9 +72,9 @@ class MiddlewareHandler
$this->reg_map[$stack_id][] = [$name, $args];
}
public function getPipeClosure(callable $callback, $stack_id)
public function getPipeClosure(callable $callback, $stack_id, ?AnnotationBase $annotation = null)
{
$pipe_func = function (array $mid_list, ...$args) use ($callback, $stack_id, &$pipe_func) {
$pipe_func = function (array $mid_list, ...$args) use ($callback, $stack_id, $annotation, &$pipe_func) {
$return = true;
try {
while (($item = array_shift($mid_list)) !== null) {
@@ -81,6 +82,9 @@ class MiddlewareHandler
// 如果是 pipeline 形式的中间件,则使用闭包回去
if (class_exists($item[0]) && is_a($item[0], PipelineInterface::class, true)) {
$resolve = resolve($item[0]);
if (method_exists($resolve, 'setAnnotation') && $annotation !== null) {
$resolve->setAnnotation($annotation);
}
if (method_exists($resolve, 'setArgs')) {
$resolve->setArgs($item[1]);
}
@@ -158,6 +162,23 @@ class MiddlewareHandler
return $final_result ?? null;
}
public function processWithAnnotation(AnnotationBase $v, callable $callback, ...$args)
{
$stack_id = $this->getStackId($callback);
unset($this->stack[$stack_id]);
$this->callable_stack[] = $callback;
// 遍历执行before并压栈并在遇到返回false后停止
try {
$mid_list = ($this->reg_map[$stack_id] ?? []);
$final_result = ($this->getPipeClosure($callback, $stack_id, $v))($mid_list, ...$args);
} finally {
array_pop($this->callable_stack);
}
return $final_result ?? null;
}
/**
* 获取正在运行的回调调用对象可能是Closure、array、string
*

View File

@@ -0,0 +1,22 @@
<?php
declare(strict_types=1);
namespace ZM\Middleware;
use ZM\Annotation\AnnotationBase;
trait NeedAnnotationTrait
{
protected ?AnnotationBase $annotation = null;
public function setAnnotation(AnnotationBase $annotation): void
{
$this->annotation = $annotation;
}
public function getAnnotation(): ?AnnotationBase
{
return $this->annotation;
}
}

View File

@@ -0,0 +1,63 @@
<?php
declare(strict_types=1);
namespace ZM\Middleware;
use OneBot\Driver\Event\WebSocket\WebSocketCloseEvent;
use OneBot\Driver\Event\WebSocket\WebSocketMessageEvent;
use OneBot\Driver\Event\WebSocket\WebSocketOpenEvent;
use ZM\Annotation\Framework\BindEvent;
use ZM\Utils\ConnectionUtil;
class WebSocketFilter implements MiddlewareInterface, PipelineInterface
{
use MiddlewareArgTrait;
use NeedAnnotationTrait;
public function handle(callable $callback, ...$params)
{
logger()->alert('正在走 Filter');
if (!$this->annotation instanceof BindEvent) {
return null;
}
if (is_a($this->annotation->event_class, WebSocketOpenEvent::class, true)) {
return $this->filterOpen(container()->get(WebSocketOpenEvent::class)) ? $callback(...$params) : null;
}
if (is_a($this->annotation->event_class, WebSocketMessageEvent::class, true)) {
return $this->filterMessageAndClose(container()->get(WebSocketMessageEvent::class)) ? $callback(...$params) : null;
}
if (is_a($this->annotation->event_class, WebSocketCloseEvent::class, true)) {
return $this->filterMessageAndClose(container()->get(WebSocketCloseEvent::class)) ? $callback(...$params) : null;
}
return $callback(...$params);
}
private function filterOpen(WebSocketOpenEvent $event): bool
{
// 过滤存在 flag 设置的情况
if (($this->args['flag'] ?? null) !== null && $this->args['flag'] !== $event->getSocketFlag()) {
return false;
}
return true;
}
private function filterMessageAndClose(WebSocketMessageEvent|WebSocketCloseEvent $event): bool
{
// 过滤存在 flag 设置的情况
if (($this->args['flag'] ?? null) !== null && $this->args['flag'] !== $event->getSocketFlag()) {
return false;
}
// 过滤连接信息
$conn = ConnectionUtil::getConnection($event->getFd());
foreach ($this->args as $k => $v) {
if (!isset($conn[$k])) {
return false;
}
if (is_string($v) && $conn[$k] !== $v) {
return false;
}
}
return true;
}
}