superbalist / php-event-pubsub
基于pub/sub的事件协议和实现
Requires
- php: >=5.6.0
- composer/semver: ^1.4
- league/json-guard: ^0.5.1
- ramsey/uuid: ^3.5
- superbalist/php-pubsub: ^2.0
Requires (Dev)
- mockery/mockery: ^0.9.5
- phpunit/phpunit: ^5.5
This package is auto-updated.
Last update: 2024-08-11 23:39:35 UTC
README
基于pub/sub的事件协议和实现
这个库基于php-pubsub包,并添加了对通过pub/sub通道监听和调度事件的支持。
安装
composer require superbalist/php-event-pubsub
集成
想要快速开始?查看以下集成
用法
简单事件
SimpleEvent
是一个接受名称和可选属性的事件。
// create a new event manager $adapter = new \Superbalist\PubSub\Adapters\LocalPubSubAdapter(); $translator = new \Superbalist\EventPubSub\Translators\SimpleEventMessageTranslator(); $manager = new \Superbalist\EventPubSub\EventManager($adapter, $translator); // dispatch an event $event = new \Superbalist\EventPubSub\Events\SimpleEvent( 'user.created', [ 'user' => [ 'id' => 1456, 'first_name' => 'Joe', 'last_name' => 'Soap', 'email' => 'joe.soap@example.org', ], ] ); $manager->dispatch('events', $event); // dispatch multiple events $events = [ new \Superbalist\EventPubSub\Events\SimpleEvent( 'user.created', [ 'user' => [ // ... ], ] ), new \Superbalist\EventPubSub\Events\SimpleEvent( 'user.created', [ 'user' => [ // ... ], ] ), ]; $manager->dispatchBatch('events', $events); // listen for an event $manager->listen('events', 'user.created', function (\Superbalist\EventPubSub\EventInterface $event) { var_dump($event->getName()); var_dump($event->getAttribute('user')); }); // listen for all events on the channel $manager->listen('events', '*', function (\Superbalist\EventPubSub\EventInterface $event) { var_dump($event->getName()); });
主题事件
TopicEvent
是一个接受主题、名称、版本和可选属性的事件。
// create a new event manager $adapter = new \Superbalist\PubSub\Adapters\LocalPubSubAdapter(); $translator = new \Superbalist\EventPubSub\Translators\TopicEventMessageTranslator(); $manager = new \Superbalist\EventPubSub\EventManager($adapter, $translator); // dispatch an event $event = new \Superbalist\EventPubSub\Events\TopicEvent( 'user', 'created', '1.0', [ 'user' => [ 'id' => 1456, 'first_name' => 'Joe', 'last_name' => 'Soap', 'email' => 'joe.soap@example.org', ], ] ); $manager->dispatch('events', $event); // listen for an event on a topic $manager->listen('events', 'user/created', function (\Superbalist\EventPubSub\EventInterface $event) { // ... }); // listen for an event on a topic matching the given version $manager->listen('events', 'user/created/1.0', function (\Superbalist\EventPubSub\EventInterface $event) { // ... }); // listen for all events on a topic $manager->listen('events', 'user/*', function (\Superbalist\EventPubSub\EventInterface $event) { // ... }); // listen for all events on the channel $manager->listen('events', '*', function (\Superbalist\EventPubSub\EventInterface $event) { // ... });
模式事件
SchemaEvent
是TopicEvent
的扩展,接受模式(schema)和可选属性。主题、名称和版本从模式中推导而来。
模式必须是以下格式:(协议)://(......)?/events/(主题)/(通道)/(版本).json
// create a new event manager $adapter = new \Superbalist\PubSub\Adapters\LocalPubSubAdapter(); $translator = new \Superbalist\EventPubSub\Translators\SchemaEventMessageTranslator(); $schemas = [ 'events/user/created/1.0.json' => json_encode([ '$schema' => 'https://json-schema.fullstack.org.cn/draft-04/schema#', 'title' => 'My Schema', 'type' => 'object', 'properties' => [ 'schema' => [ 'type' => 'string', ], 'user' => [ 'type' => 'object', ], ], 'required' => [ 'schema', 'user', ], ]), ]; $loader = new \League\JsonGuard\Loaders\ArrayLoader($schemas); $dereferencer = new \League\JsonGuard\Dereferencer(); $dereferencer->registerLoader($loader, 'array'); $validator = new \Superbalist\EventPubSub\Validators\JSONSchemaEventValidator($dereferencer); $manager = new \Superbalist\EventPubSub\EventManager($adapter, $translator, $validator); // dispatch an event $event = new \Superbalist\EventPubSub\Events\SchemaEvent( 'http://schemas.my-website.org/events/user/created/1.0.json', [ 'user' => [ 'id' => 1456, 'first_name' => 'Joe', 'last_name' => 'Soap', 'email' => 'joe.soap@example.org', ], ] ); $manager->dispatch('events', $event); // the listen expressions are the same as those used for TopicEvents.
自定义事件
您可以通过编写一个实现EventInterface
接口的类来轻松使用自定义事件结构。然后您需要编写一个自定义翻译器来将传入的消息转换为您自己的事件对象。
您的事件必须实现以下方法。
/** * Return the event name. * * @return string */ public function getName(); /** * Return all event attributes. * * @return array */ public function getAttributes(); /** * Return an event attribute. * * @param string $name * @return mixed */ public function getAttribute($name); /** * Set an event attribute. * * @param string|array $name * @param mixed $value */ public function setAttribute($name, $value = null); /** * Check whether or not an event has an attribute. * * @param string $name * @return bool */ public function hasAttribute($name); /** * Check whether or not the event matches the given expression. * * @param string $expr * @return bool */ public function matches($expr); /** * Return the event in a message format ready for publishing. * * @return mixed */ public function toMessage();
翻译器
翻译器用于将传入的消息转换为事件。
该包附带了一个SimpleEventMessageTranslator
、TopicEventMessageTranslator
和SchemaEventMessageTranslator
。
自定义翻译器
您可以通过实现MessageTranslatorInterface
接口来轻松编写自己的翻译器。
您的翻译器必须实现以下方法。
/** * @param mixed $message * @return null|EventInterface */ public function translate($message);
验证器
验证器是一个可选组件,用于在调度事件时验证事件。
JSONSchemaEventValidator
此包附带了一个JSONSchemaEventValidator
,它适用于SchemaEvent
类型的事件。
此验证器使用JSON Schema Spec和JSON Guard PHP包来验证事件。
请参阅上面的“模式事件”部分和JSON Guard文档以获取用法示例。
自定义验证器
您可以通过实现EventValidatorInterface
接口来编写自己的验证器。
您的验证器必须实现以下方法。
/** * @param EventInterface $event * @return ValidationResult */ public function validate(EventInterface $event);
属性注入器
属性注入器允许您在事件调度时自动将属性注入到事件中。
该库附带了一些内置的注入器。
- DateAttributeInjector - 注入一个
date
键,其值为ISO 8601日期时间 - GenericAttributeInjector - 注入一个自定义的
key
和value
- HostnameAttributeInjector - 注入一个
hostname
键,其值为服务器主机名 - Uuid4AttributeInjector - 注入一个
uuid
键,其值为UUID-4
您可以通过实现AttributeInjectorInterface
或通过传递一个可调用的函数(该函数返回一个包含'key'和'value'的数组)到事件管理器来编写自己的注入器。
您的注入器必须实现以下方法。
/** * @return string */ public function getAttributeKey(); /** * @return mixed */ public function getAttributeValue();
这里是一个使用示例,展示了类和可调用函数。
自定义类
use Superbalist\EventPubSub\AttributeInjectorInterface; class UserAttributeInjector implements AttributeInjectorInterface { /** * @return string */ public function getAttributeKey() { return "user"; } /** * @return mixed */ public function getAttributeValue() { return [ 'id' => 2416334, 'email' => 'john.doe@example.org', 'first_name' => 'John', 'last_name' => 'Doe', ]; } } // create a new event manager $adapter = new \Superbalist\PubSub\Adapters\LocalPubSubAdapter(); $translator = new \Superbalist\EventPubSub\Translators\SimpleEventMessageTranslator(); $manager = new \Superbalist\EventPubSub\EventManager($adapter, $translator); $manager->addAttributeInjector(new UserAttributeInjector()); // or $manager = new \Superbalist\EventPubSub\EventManager($adapter, $translator, null, [new UserAttributeInjector()]);
可调用函数
// create a new event manager $adapter = new \Superbalist\PubSub\Adapters\LocalPubSubAdapter(); $translator = new \Superbalist\EventPubSub\Translators\SimpleEventMessageTranslator(); $manager = new \Superbalist\EventPubSub\EventManager($adapter, $translator); $manager->addAttributeInjector(function () { return [ 'key' => 'user', 'value' => [ 'id' => 2416334, 'email' => 'john.doe@example.org', 'first_name' => 'John', 'last_name' => 'Doe', ], ]; });
错误处理
该库支持错误处理器,用于处理事件转换失败、监听表达式失败和验证失败的情况。
您可以将可调用函数传递给EventManager构造函数,或按照以下方式设置
// create a new event manager $adapter = new \Superbalist\PubSub\Adapters\LocalPubSubAdapter(); $translator = new \Superbalist\EventPubSub\Translators\SimpleEventMessageTranslator(); $manager = new \Superbalist\EventPubSub\EventManager($adapter, $translator); // hook into translation failures $manager->setTranslateFailHandler(function ($message) { // the message failed to translate into an event }); // hook into listen expression failures $manager->setListenExprFailHandler(function (\Superbalist\EventPubSub\EventInterface $event, $expr) { // the event didn't match the listen expression // this isn't really an error, but can be useful for debug }); // hook into validation failures $manager->setValidationFailHandler(function (\Superbalist\EventPubSub\ValidationResult $result) { // the event failed validation var_dump($result->errors()); });
示例
该库提供了不同类型事件的示例和一个Dockerfile,用于运行示例脚本。
运行make up
。
您将进入/opt/php-event-pubsub
目录下的bash
提示符。
要运行示例
$ php examples/SimpleEventExample.php $ php examples/TopicEventExample.php $ php examples/SchemaEventExample.php