retmix / centrifugo-broadcaster-fix
支持 Laravel 8-9.x 和 Centrifugo >= 2.8.1 的 Centrifugo 广播器
2.x-dev
2023-03-13 23:25 UTC
Requires
- php: ^8.0|^8.1
- ext-json: *
- guzzlehttp/guzzle: ~6.0|^7.0
- laravel/framework: ^8.75|^9.0
Requires (Dev)
- orchestra/testbench: ^v7.4.0
- phpunit/phpunit: ^9.5
This package is not auto-updated.
Last update: 2024-09-25 04:51:52 UTC
README
文档 EN | RU
Laravel Centrifugo 4 广播器
适用于 Laravel 8.75 - 9.x 的 Centrifugo 4 版本广播驱动程序
对于 Centrifugo 2.8 - 3.x,请使用 版本 1.2.6
特性
- 兼容最新的 Centrifugo 4.x 🚀
- 封装了 Centrifugo HTTP API 🔌
- 使用 JWT 令牌(HMAC 算法)进行身份验证 🗝️
要求
- PHP >= 8.0
- Laravel 8.75 - 9.x
- guzzlehttp/guzzle 6 - 7
- Centrifugo 服务器 4.x 或更高版本(见 此处)
安装
使用 composer 安装此包
composer req opekunov/laravel-centrifugo-broadcaster
打开您的 config/app.php
并取消注释此行
return [ // .... // 'providers' => [ // Uncomment BroadcastServiceProvider App\Providers\BroadcastServiceProvider::class, ], // .... // ];
打开您的 config/broadcasting.php
并添加新的 connection
如下所示
return [ // .... // 'centrifugo' => [ 'driver' => 'centrifugo', 'secret' => env('CENTRIFUGO_SECRET'), 'apikey' => env('CENTRIFUGO_APIKEY'), 'api_path' => env('CENTRIFUGO_API_PATH', '/api'), // Centrifugo api endpoint (default '/api') 'url' => env('CENTRIFUGO_URL', 'https://:8000'), // centrifugo api url 'verify' => env('CENTRIFUGO_VERIFY', false), // Verify host ssl if centrifugo uses this 'ssl_key' => env('CENTRIFUGO_SSL_KEY', null), // Self-Signed SSl Key for Host (require verify=true), 'show_node_info' => env('CENTRIFUGO_SHOW_NODE_INFO', false), // Show node info in response with auth token 'timeout' => env('CENTRIFUGO_TIMEOUT', 3), // Float describing the total timeout of the request to centrifugo api in seconds. Use 0 to wait indefinitely (the default is 3) 'tries' => env('CENTRIFUGO_TRIES', 1), //Number of times to repeat the request, in case of failure (the default is 1) 'token_expire_time' => env('CENTRIFUGO_TOKEN_EXPIRE', 120), //Default token expire time. Used in channel subscriptions /broadcasting/auth ], // .... // ];
您还应在您的 .env
文件中添加这两行
CENTRIFUGO_SECRET=token_hmac_secret_key-from-centrifugo-config
CENTRIFUGO_APIKEY=api_key-from-centrifugo-config
CENTRIFUGO_URL=https://:8000
这些行是可选的
CENTRIFUGO_SSL_KEY=/etc/ssl/some.pem
CENTRIFUGO_VERIFY=false
CENTRIFUGO_API_PATH=/api
CENTRIFUGO_SHOW_NODE_INFO=false
CENTRIFUGO_TIMEOUT=10
CENTRIFUGO_TRIES=1
CENTRIFUGO_TOKEN_EXPIRE=120
别忘了更改 .env 文件中的 BROADCAST_DRIVER
设置!
BROADCAST_DRIVER=centrifugo
基本用法
要配置 Centrifugo 服务器,请参阅 官方文档
有关广播事件的更多信息,请参阅 Laravel 官方文档
频道身份验证示例
Laravel
// routes/channels.php // IMPORTANT. In Centrifugo 4, the '$' character in front of the private channel is considered obsolete. Do not use it. https://centrifugal.dev/docs/server/channels#private-channel-prefix- Broadcast::channel('namespace:channel', function (){ // Some auth logic for example: return \Auth::user()->group === 'private-channel-group'; }); Broadcast::channel('namespace:channel-{id}', function ($user, $id){ return $user->id === $id; });
前端。请参阅文档 centrifugal/centrifuge-js
// Example: import { Centrifuge } from 'centrifuge'; // Set the base path of Laravel broadcasting. // Don't forget to add 'path' => [..., 'broadcasting/auth'] to your application's cors.php file const subscribeTokenEndpoint = 'http://127.0.0.1/broadcasting/auth' const centrifuge = new Centrifuge('ws://:8001/connection/websocket', { //CONNECTION_TOKEN must be obtained from Centrifuge::generateConnectionToken(...) token: 'CONNECTION_TOKEN' }) // Set the subscription const sub = centrifuge.newSubscription('test:test', { getToken: function (ctx) { return customGetToken(subscribeTokenEndpoint, ctx); }, }) // Getting a subscription token from your Laravel application. // Important: In this example, getting a subscription token is implemented through basic fetch() without passing parameters to identify the user in your Laravel application. Use methods appropriate for your application function customGetToken(endpoint, ctx) { return new Promise((resolve, reject) => { fetch(endpoint, { method: 'POST', headers: new Headers({ 'Content-Type': 'application/json' }), body: JSON.stringify(ctx) }) .then(res => { if (!res.ok) { throw new Error(`Unexpected status code ${res.status}`); } return res.json(); }) .then(data => { resolve(data.token); }) .catch(err => { reject(err); }); }); } sub.subscribe(); centrifuge.connect();
广播示例
使用 artisan 创建事件(例如 SendMessage)php artisan make:event SendMessageEvent
<?php // App/Events/SendMessageEvent.php namespace App\Events; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; //Use "implements ShouldBroadcast" if you want add event to queue class SendMessageEvent implements ShouldBroadcastNow { use Dispatchable, InteractsWithSockets, SerializesModels; /** * @var string Message text */ private $messageText; public function __construct(string $messageText) { $this->messageText = $messageText; } /** * The event's broadcast name. * * @return string */ public function broadcastAs() { //example event broadcast name. Show in Web Socket JSON return 'message.new'; } /** * Get the data to broadcast. * * @return array */ public function broadcastWith() { return ['message' => $this->messageText]; } /** * Get the channels the event should broadcast on. * * @return \Illuminate\Broadcasting\Channel|array */ public function broadcastOn() { return new Channel('public:chat'); // or return new PrivateChannel('private:chat'); // in Centrifuge 4 all channels are protected, and the '$' prefix is considered obsolete. https://centrifugal.dev/docs/server/channels#private-channel-prefix- } }
简单的客户端使用示例
<?php declare(strict_types = 1); namespace App\Http\Controllers; use Opekunov\Centrifugo\Centrifugo; use Illuminate\Support\Facades\Auth; class ExampleController { public function example(Centrifugo $centrifugo) { //or $centrifugo = new Centrifugo(); //or centrifugo() // Send message into channel $centrifugo->publish('news', ['message' => 'Hello world']); // Generate connection token $token = $centrifugo->generateConnectionToken((string)Auth::id(), 0, [ 'name' => Auth::user()->name, ]); // Generate subscription token $expire = now()->addDay(); //or you can use Unix: $expire = time() + 60 * 60 * 24; $apiSign = $centrifugo->generateSubscriptionToken((string)Auth::id(), 'channel', $expire, [ 'name' => Auth::user()->name, ]); //Get a list of currently active channels. $centrifugo->channels(); //Get channel presence information (all clients currently subscribed on this channel). $centrifugo->presence('news'); } }
可用方法
许可协议
MIT 许可协议 (MIT)。有关更多信息,请参阅 许可文件