使用事件注册器进行swoole代码封装

在使用swoole的时候,事件回调很难维护与编写,写起来很乱。特别在封装一些代码的时候,使用这种注册,先注册用户自己定义的,然后注册些默认的事件函数。

Server.php

class Server
{
    public function __construct()
    {
        $server   = new \swoole_http_server(‘0.0.0.0‘, 9501);
        // 创建一个注册器,其实这个很简单,就是将一些要执行的回调函数进统一以回调名为键,要执行的方法放在一个数组中[‘workerStart‘=>[callback]]
        $register = new EventRegister();
        // 首先注册默认的
        $this->finalHook($register);
        // 然后是用户自定义的,所以只给定应用层这些接口来写回调
        WPHPEvent::mainServerCreate($register);
        $events = $register->all();

        foreach ($events as $event => $callback) {
            $server->on($event, function () use ($callback) {
                $args = func_get_args();
                foreach ($callback as $item) {
                    // 可以使用这三种方式调用
//                    call_user_func($item, ...$args);
//                    call_user_func_array($item, $args);
                    $item(...$args);
                }
            });
        }
        $server->start();

    }

    private function finalHook(EventRegister $register)
    {

        $register->add(‘workerStart‘, function () {
            cli_set_process_title(‘wphp-work-zhangsan‘);
        });
        // ...

        $register->add(‘request‘, function ($request, $response) {
            $response->header("Content-Type", "text/html; charset=utf-8");
            $response->end("<h1>Hello Swoole. #" . rand(1000, 9999) . "</h1>");
        });
    }
}
MultiContainer.php
class MultiContainer
{
    private $container = [];
    private $allowKeys = null;

    public function __construct(array $allowKeys)
    {
        $this->allowKeys = $allowKeys;
    }

    public function add($key, $item)
    {
        if (!in_array($key, $this->allowKeys)) {
            return false;
        }
        $this->container[$key][] = $item;
        return $this;
    }

    public function set($key, $item)
    {
        if (!in_array($key, $this->allowKeys)) {
            return false;
        }
        $this->container[$key] = [$item];
        return $this;
    }

    public function delete($key)
    {
        unset($this->container[$key]);
        return $this;
    }

    public function get($key)
    {
        if (isset($this->container[$key])) {
            return $this->container[$key];
        }
        return null;
    }

    public function all()
    {
        return $this->container;
    }

}

Event.php

class Event extends MultiContainer
{
    public function add($key, $item)
    {
        if (is_callable($item)) {
            return parent::add($key, $item);
        } else {
            return false;
        }
    }

    public function set($key, $item)
    {
        if (is_callable($item)) {
            return parent::set($key, $item);
        }
    }

}

EventRegister.php

class EventRegister extends Event
{
    public function __construct()
    {
        parent::__construct([
            ‘start‘, ‘shutdown‘, ‘workerStart‘, ‘workerStop‘, ‘workerExit‘, ‘timer‘,
            ‘connect‘, ‘receive‘, ‘packet‘, ‘close‘, ‘bufferFull‘, ‘bufferEmpty‘, ‘task‘,
            ‘finish‘, ‘pipeMessage‘, ‘workerError‘, ‘managerStart‘, ‘managerStop‘,
            ‘request‘, ‘handShake‘, ‘message‘, ‘open‘
        ]);
    }

    public function add($key, $item)
    {
        if (!parent::add($key, $item)) {
            throw new \Exception(‘错误的调用方式‘);
        }
        return $this;
    }

    public function set($key, $item)
    {
        if (!parent::set($key, $item)) {
            throw new \Exception(‘错误的调用方式‘);
        }
        return $this;
    }
}

WPHPEvent.php

class WPHPEvent
{
    public static function mainServerCreate($register)
    {
        $register->add(‘workerStart‘, function () {
            echo 22;
        });
    }
}

原文地址:https://www.cnblogs.com/shiwenhu/p/9674218.html

时间: 2024-08-01 12:42:56

使用事件注册器进行swoole代码封装的相关文章

事件查看器常见ID代码解释

ID 类型 来   源 代 表 的 意 义 举 例 解 释 2 信息 Serial 在验证 \Device\Serial1 是否确实是串行口时,系统检测到先进先出方式(fifo).将使用该方式. 17 错误 W32Time 时间提供程序 NtpClient: 在 DNS 查询手动配置的对等机器 'time.windows.com,0x1' 时发生一个错误. NtpClient 将在 15 分钟内重试 NDS 查询. 错误为: 套接字操作尝试一个无法连接的主机. (0x80072751) 20 警

MVP+Dagger2+Rxjava+Retrofit+GreenDao 开发的小应用,包含新闻、图片、视频3个大模块,代码封装良好

练习MVP架构开发的App,算是对自己学过的知识做一个总结,做了有一段时间,界面还算挺多的,代码量还是有的,里面做了大量封装,整体代码整理得很干净,这个我已经尽力整理了.不管是文件(java.xml.资源文件)命名,还是布局设计尽量简单简洁,我对自己写代码的规范还是有信心的- -.代码不会写的很复杂,整个代码结构有很高的统一度,结构也比较简单清晰,方便理解.里面做了大量的封装,包括基类的构建和工具类的封装,再配合Dagger2的使用可以极大地减轻V层(Activity和Fragment)的代码,

Windows 事件查看器(收集)

原文:Windows 事件查看器(收集) 事件查看器相当于一本厚厚的系统日志,可以查看关于硬件.软件和系统问题的信息,也可以监视 Windows 的安全事件 提示:除了可以在"控制面板→管理工具"中找到"事件查看器"的踪影外,也可以在"运行"对话框中 手工键入"%SystemRoot%\system32\eventvwr.msc /s"打开事件查看器窗口. 1. 应用程序日志 包含由应用程序或系统程序记录的事件,主要记录程序运

自定义的事件管理器

自定义的事件管理器 周银辉 大多数框架下都提供了事件管理器的,但不使用框架时为了让事件发送者和事件接收者之间解耦,就可以如下写个简单的 public enum EventAdministratorEventTypes { ApplicationStartup, //在这里添加你需要的事件 } public class EventAdministratorEventArgs : EventArgs { public object Arg { get; protected set; } public

MVP+Dagger2+Rxjava+Retrofit+GreenDao 开发的小应用,包括新闻、图片、视频3个大模块,代码封装良好

练习MVP架构开发的App,算是对自己学过的知识做一个总结,做了有一段时间,界面还算挺多的.代码量还是有的,里面做了大量封装,总体代码整理得非常干净,这个我已经尽力整理了. 不管是文件(java.xml.资源文件)命名.还是布局设计尽量简单简洁,代码不会写的非常复杂.整个代码结构有非常高的统一度,结构也比較简单清晰,方便理解.里面做了大量的封装,包含基类的构建和工具类的封装.再配合Dagger2的使用能够极大地减轻V层(Activity和Fragment)的代码,假设你有看源代码的话你会发现大部

DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件

本节目录 一 认证组件 二 权限组件 三 频率组件 四 URL注册器 五 响应器 六 分页组件 七 xxx 八 xxx 一 认证组件 1. 局部认证组件 我们知道,我们不管路由怎么写的,对应的视图类怎么写的,都会走到dispatch方法,进行分发, 在咱们看的APIView类中的dispatch方法的源码中,有个self.initial(request, *args, **kwargs),那么认证.权限.频率这三个默认组件都在这个方法里面了,如果我们自己没有做这三个组件的配置,那么会使用源码中默

使用Windows事件查看器调试崩溃

本文讨论如何使用Windows事件查看器获取实际崩溃的模块以及代码中崩溃的位置.示例代码是用C++编写的,以生成不同类型的崩溃,例如访问冲突和堆栈溢出. 简介 我经常听同事和QA那里听说,一个特定的崩溃很容易在客户机上重现,而不是在他们的机器上重现.这是一个棘手的问题,因为开发人员无法在客户机上调试崩溃.最终的结果是支持团队和客户之间无休止的沟通,甚至是现场会议.很少有聪明的程序员自己开发一个崩溃日志系统来确定导致崩溃的代码.很少有人会在代码中全面地实现try-catch块,以缩小问题的范围.

事件管理器

项目开发过程中经常会用到代理事件,为方便管理,避免代码混乱,需要一个总的事件管理器: using UnityEngine; using System.Collections; using System.Collections.Generic; using System; public class EventManager<T> { private static Dictionary<EventType,List<Action<T>>> eventDic =

C#事件の事件聚合器

事件聚合器用于集中管理事件的订阅(Subscribe)和处理(Handle),要使用事件聚合器,首先要理解:事件(event)本质上是一个类. 传统的+=和-=不足: 1.管理很麻烦:2.不方便扩展. 所以尝试使用事件聚合器来解决这个问题. 首先,使用一个统一的接口来实现事件的统一标记: public interface IEvent{ } 事件,需要有对应的事件处理器(EventHandler),这里使用一个统一的接口 IEventHandler 来进行统一,IEventHandler 只包含