le0m / yii2-broadcasting
WebSocket消息广播模块
1.0.0
2019-05-18 14:04 UTC
Requires
- yiisoft/yii2: ~2.0.16
- yiisoft/yii2-redis: ~2.0.0
This package is auto-updated.
Last update: 2024-09-19 02:27:24 UTC
README
此组件是 MKiselev/yii2-broadcasting 的延续。它已被重新组织并更新,以与Yii2 2.0.16一起使用。
您可以使用它通过WebSocket处理通知。
需求
- 一个运行中的 laravel-echo-server 实例,用于处理Socket.io服务器和频道认证
- 此包会安装 yiisoft/yii2-redis,用于通过Redis与Socket.io服务器共享消息
- 前端需要安装 Laravel Echo 和 socket.io-client,以打开WebSocket并监听通知
安装
安装此扩展的首选方法是使用 composer。
运行
php composer.phar require --prefer-dist le0m/yii2-broadcasting:"~1.0.0"
或添加
"le0m/yii2-broadcasting": "~1.0.0"
到您的composer.json的require部分。
配置
配置组件以使用广播器
'modules' => [ // configure a redis connection 'redis' => [ 'class' => 'yii\redis\Connection', 'hostname' => 'localhost', 'port' => 6379, 'database' => 0, ], 'broadcasting' => [ 'class' => 'le0m\broadcasting\BroadcastManager', 'broadcaster' => [ 'class' => 'le0m\broadcasting\broadcasters\RedisBroadcaster', // use the redis connection component (default) or define a new one 'redis' => 'redis', 'channels' => [ // authorization callback for private and presence channels 'comments.{postId}' => function (yii\web\User $user, $postId) { // use basic roles or RBAC return $user->can('doSomething', ['post' => $postId]); }, ], ], ] ]
有几种广播工具可供选择
- NullBroadcaster 不做任何事情,只是一个占位符
- LogBroadcaster 将事件广播到应用程序日志
- RedisBroadcaster 使用Redis的Pub/Sub功能进行广播
用法
设置Laravel Echo服务器
见 文档。
服务器端
添加操作以授权用户访问私有和存在频道
class NotificationController extends Controller { // ... public function behaviors() { return [ // ... 'authenticator' => [ // define your authenticator behavior 'class' => HttpBearerAuth::class, ] ]; } public function actions() { return [ 'auth' => [ 'class' => 'le0m\broadcasting\actions\AuthAction' ] ]; } // ... }
通过扩展 le0m\broadcasting\BroadcastEvent
定义一个新的事件进行广播,您定义的公共属性将被发送为消息负载
namespace common\models; use le0m\broadcasting\channels\PrivateChannel; use le0m\broadcasting\BroadcastEvent; class MessageEvent extends BroadcastEvent { public $text; public $author; public $time; private $_postId; public function broadcastOn() { return new PrivateChannel('comments.' . $this->getPostId()); } public function broadcastAs() { return 'new'; } public function getPostId() { return $this->_postId; } public function setPostId($postId) { $this->_postId = $postId; } }
然后在需要时进行广播
$event = new MessageEvent([ 'text' => $text, 'author' => $user->username, 'time' => time() ]); $event->toOthers()->broadcast();
使用 toOthers
标志将消息广播到所有频道用户 除了 发送者。使用socket ID头部排除发送者。
客户端
导入并初始化 Echo
,然后开始监听通知
import Echo from 'laravel-echo' import io from 'socket.io-client' let postId = 13; const echo = new Echo({ broadcaster: 'socket.io', // will default to port 6001 of host host: window.location.hostname, authEndpoint: '/api/rest/v1/notification/auth', // this can be a whole URL client: io, // not needed if `io` is globally defined auth: { headers: { Authorization: `Bearer ...` // set headers needed for the authorization request to private and presence channels } }, transports: ['websocket', 'polling'] // give websocket precedence }) // attach connect event listener, to wait for a socket ID this.echo.connector.socket.on('connect', () => { // console.log(`internal socket id:`, this.echo.connector.socket.id) console.log(`socket connected with ID:`, this.echo.connector.socketId()) // attach listen events this.echo .private(`comments.${postId}`) // the initial dot is to ignore event namespace (derived from backend event class) .listen('.new', (event) => { console.log(`received comment from Echo:`, event) }) })
这里我们等待Socket.io连接器的 connect
事件,在附加我们的回调之前获取socket ID。
其他
- 使用Docker的Echo服务器(底部)
- 参考资料
- 变更日志