jul6art / push-bundle
Symfony 实时通知组件
v1.0.16
2021-01-29 23:51 UTC
Requires
- php: ^7.4
- jul6art/core-bundle: ^1.0
- symfony/config: ^4.4 || ^5.0
- symfony/dependency-injection: ^4.4 || ^5.0
- symfony/http-kernel: ^4.4 || ^5.0
- symfony/mercure-bundle: *
- symfony/messenger: ^4.4 || ^5.0
Requires (Dev)
- dama/doctrine-test-bundle: ^6.0
- phpunit/phpunit: ^7.0
- symfony/phpunit-bridge: ^4.4 || ^5.0
- symfony/var-dumper: ^4.4 || ^5.0
README
jul6art/push-bundle
Symfony 实时通知组件
⚠️ 正在进行中,请保持冷静。好消息:该项目正在维护中!
需求
- php ^7.4 || ^8.0
- symfony ^4.4 || ^5.0
- mercure
安装
composer require jul6art/push-bundle
根据您的操作系统下载 mercure hub 并将其安装到项目的根目录中。对于每个版本,资产部分列出了操作系统的实现。文件夹必须包含 mercure bin。将此文件夹重命名为 mercure。
EventSource Polyfill
npm install event-source-polyfill
并在客户端导入它,以便在 IE 和 Edge 上实现推送功能
生成新的 JWT 令牌(可选)
前往 jwt.io 并将您的未来 mercure 密钥(默认为 !ChangeMe!)放入 verify signature 文本区域,并将此数组放入 payload 文本区域
{ "mercure": { "publish": [] } }
因为数组为空,所以 Symfony 应用程序只能发布公开更新(有关更多信息,请参阅 symfony/mercure-bundle 的 授权 部分)。
然后将生成的令牌存储在您的 .env 文件中作为 MERCURE_JWT_TOKEN 参数
启动 mercure 服务器
默认令牌使用密钥签名:!ChangeMe!
CORS_ALLOWED_ORIGINS 是客户端 URL 和端口。可以是 * 或域名列表。ADDR 是服务器 URL,3000 是 mercure 服务器的端口
JWT_KEY='!ChangeMe!' ADDR='localhost:3000' ALLOW_ANONYMOUS=1 CORS_ALLOWED_ORIGINS="https://:80" ./mercure/mercure
⚠️ 默认情况下,推送消息是异步的,因此您需要在终端中启动一个爬虫来解队列消息并发送它
bin/console messenger:consume async_priority_high --time-limit 600
与 api-platform 一起使用
服务器端
/** * @ApiResource(mercure=true) */ class SomeTopic {}
客户端
import {EventSourcePolyfill} from "../polyfills/Polyfills"; export default class MercureProvider { provide = () => { const publishUrl = new URL('http://publish.url:3000/hub'); publishUrl.searchParams.append("topic", "/some_topic"); publishUrl.searchParams.append("topic", "/some_topic/{id}"); const es = new EventSourcePolyfill(publishUrl, { headers: { 'Authorization': 'Bearer ' + YOUR_MERCURE_JWT_TOKEN } }); es.onmessage = e => { const data = JSON.parse(e.data); const regex = /\/api\/(?<type>\w+)\//gm; const match = regex.exec(data['@id']); if (null !== match) { const event = new CustomEvent(match.groups.type, { "data": data }); document.dispatchEvent(event); } }; } }; // somewhere else document.addEventListener('...', function() { // what you need });
不使用 api-platform
服务器端
use Jul6Art\PushBundle\Service\Traits\PusherAwareTrait; /** * Class RequestEventSubscriber */ class SomeService { use PusherAwareTrait; public function function(): void { $this->pusher->push('/some/topic', ['test' => true]); } }
同步(可选)
push: async: false
其他 messenger 消息(可选)
push: routing: 'PathToSomeAsyncMessage': async_priority_high
可以是 async_priority_high 或 async_priority_low 或 sync
可异步注解(可选)
我的实体
/** * @ORM\Entity(repositoryClass=MyClassRepository::class) * @Asyncable(eventClass="App\Event\MyClassEvent") */ class MyClass { }
我的实体事件
<?php namespace App\Event; use App\Entity\MyClass; use Jul6Art\CoreBundle\Event\AbstractEvent; /** * Class MyClassEvent */ class MyClassEvent extends AbstractEvent { public const CREATED = 'event.my_class.created'; public const DELETED = 'event.my_class.deleted'; public const EDITED = 'event.my_class.edited'; public const VIEWED = 'event.my_class.viewed'; /** * @var MyClass */ private $myClass; public function __construct(MyClass $myClass) { parent::__construct(); $this->myClass = $myClass; } public function getMyClass(): MyClass { return $this->myClass; } public function setMyClass(MyClass $myClass): MyClassEvent { $this->myClass = $myClass; return $this; } }
监听这些事件类的所有动作将在异步中进行
您还可以指定要跟踪哪些 doctrine 事件
/** * @ORM\Entity(repositoryClass=MyClassRepository::class) * @Asyncable(eventClass="App\Event\MyClassEvent", events={"postLoad", "postPersist"}) */ class MyClass { }
可用事件有
- postLoad
- postPersist
- postUpdate
- preRemove
许可证
Push Bundle 是开源软件,许可协议为 MIT 许可证。
© 2023 dev in the hood