jul6art/push-bundle

Symfony 实时通知组件

安装: 18

依赖: 0

建议: 0

安全: 0

星标: 3

关注者: 2

分支: 0

开放问题: 0

类型:symfony-bundle

v1.0.16 2021-01-29 23:51 UTC

This package is auto-updated.

Last update: 2024-09-04 20:44:49 UTC


README

logo dev in the hood

License Version

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_highasync_priority_lowsync

可异步注解(可选)

我的实体

/**
 * @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