mvanduijker / laravel-mercure-broadcaster
Mercure 广播器
Requires
- php: ^7.4|^8.0
- illuminate/broadcasting: ~6.0|~7.0|~8.0|~9.0|~10.0|~11.0
- lcobucci/jwt: ~4.0
- symfony/mercure: ~0.4
Requires (Dev)
- larapack/dd: ^1.0
- orchestra/testbench: ~4.0|~5.0|~6.0|~7.0|~8.0|~9.0
- phpunit/phpunit: ^9.4|^10.0
- symfony/process: ~4.4|~5.0|~6.0|~7.0
README
Laravel 的 Mercure 广播器,用于轻松实现服务器端事件。
安装
确保您已安装并运行 Mercure。请参阅他们的文档了解如何操作。(很简单)
通过编辑 config/broadcasting.php
配置 Laravel 使用 Mercure 广播器,例如
<?php return [ 'default' => env('BROADCAST_DRIVER', 'mercure'), 'connections' => [ // ... 'mercure' => [ 'driver' => 'mercure', 'url' => env('MERCURE_URL', 'https://:3000/.well-known/mercure'), 'secret' => env('MERCURE_SECRET', 'aVerySecretKey'), ], ], ];
用法
添加实现 ShouldBroadcast 接口的事件,例如在 https://laravel.net.cn/docs/master/broadcasting#defining-broadcast-events
<?php namespace App\Events; use Duijker\LaravelMercureBroadcaster\Broadcasting\Channel; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; class NewsItemCreated implements ShouldBroadcast { /** * @var NewsItem */ public $newsItem; public function __construct(NewsItem $newsItem) { $this->newsItem = $newsItem; } public function broadcastOn() { return new Channel('http://example/news-items'); } }
在前端进行类似操作
var es = new EventSource('https://:3000/.well-known/mercure?topic=' + encodeURIComponent('http://example/news-items')); es.addEventListener('message', (messageEvent) => { var eventData = JSON.parse(messageEvent.data); console.log(eventData); });
私有频道与通过套接字进行广播略有不同。私有频道是 Mercure 内置的,并使用 jwt 令牌进行安全保护。
首先创建一个 http 中间件,以便我们可以使用令牌生成 Mercure 认证 cookie。别忘了将中间件添加到路由中!
示例
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Http\Response; use Illuminate\Support\Facades\Cookie; use Lcobucci\JWT\Configuration; use Lcobucci\JWT\Signer\Hmac\Sha256; use Lcobucci\JWT\Signer\Key\InMemory; class MercureBroadcasterAuthorizationCookie { public function handle(Request $request, Closure $next) { /** @var Response $response */ $response = $next($request); if (!method_exists($response, 'withCookie')) { return $response; } return $response->withCookie($this->createCookie($request->user(), $request->secure())); } private function createCookie($user, bool $secure) { // Add topic(s) this user has access to // This can also be URI Templates (to match several topics), or * (to match all topics) $subscriptions = [ "http://example/user/{$user->id}/direct-messages", ]; $jwtConfiguration = Configuration::forSymmetricSigner( new Sha256(), InMemory::plainText(config('broadcasting.connections.mercure.secret')) ); $token = $jwtConfiguration->builder() ->withClaim('mercure', ['subscribe' => $subscriptions]) ->getToken($jwtConfiguration->signer(), $jwtConfiguration->signingKey()) ->toString(); return Cookie::make( 'mercureAuthorization', $token, 15, '/.well-known/mercure', // or which path you have mercure running parse_url(config('app.url'), PHP_URL_HOST), $secure, true ); } }
由于 Laravel 默认对 cookie 进行加密和解密,请务必在 App\Http\Middleware\EncryptCookies
中添加对 mercureAuthorization
cookie 的 异常。
示例事件
<?php namespace App\Events; use Duijker\LaravelMercureBroadcaster\Broadcasting\Channel; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; class DirectMessageCreated implements ShouldBroadcast { /** * @var DirectMessage */ public $directMessage; public function __construct(DirectMessage $directMessage) { $this->directMessage = $directMessage; } public function broadcastOn() { return new Channel( "http://example/user/{$this->directMessage->user_id}/direct-messages", true ); } }
示例前端
var es = new EventSource('https://:3000/.well-known/mercure?topic=' + encodeURIComponent('http://example/user/1/direct-messages'), { withCredentials: true }); es.addEventListener('message', (messageEvent) => { var eventData = JSON.parse(messageEvent.data); console.log(eventData); });
高级用法
如果您想生成自己的 JWT,可以通过覆盖 mvanduijker.mercure_broadcaster.publisher_jwt
服务来实现。如果您想自定义声明、使用其他签名算法等,请执行此操作。它期望返回包含 JWT 的字符串。默认 JWT 的生成示例:https://github.com/mvanduijker/laravel-mercure-broadcaster/blob/master/src/LaravelMercureBroadcasterServiceProvider.php#L32
请确保您还在 cookie 中间件中进行了更改。
进一步阅读
请确保您阅读了 Mercure 的文档以及如何安全地运行它(在 https 后面)。
测试
composer test
变更日志
请参阅 CHANGELOG 了解最近更改的详细信息。
贡献
请参阅 CONTRIBUTING 了解详细信息。
鸣谢
许可
MIT 许可证(MIT)。请参阅 许可文件 了解更多信息。