le0m/yii2-broadcasting

WebSocket消息广播模块

安装: 606

依赖: 0

建议者: 0

安全: 0

星标: 3

关注者: 1

分支: 5

开放问题: 0

类型:yii2-extension

1.0.0 2019-05-18 14:04 UTC

This package is auto-updated.

Last update: 2024-09-19 02:27:24 UTC


README

Latest Stable Version License Monthly Downloads Total Downloads

此组件是 MKiselev/yii2-broadcasting 的延续。它已被重新组织并更新,以与Yii2 2.0.16一起使用。

您可以使用它通过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]);
                },
            ],
        ],
    ]
]

有几种广播工具可供选择

  1. NullBroadcaster 不做任何事情,只是一个占位符
  2. LogBroadcaster 将事件广播到应用程序日志
  3. 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。

其他