场景
- 一个类知乎网站的私信功能
分析
- 实现方式
- vue
- laravel echo
- pusher
- supervisor
- 私信功能的实现见我的另一篇博文 网站私信表(留言表)的设计 && 空间换性能的思路
实现(pusher driver)
- 安装
- composer require pusher/pusher-php-server “~3.0”
- npm install --save laravel-echo pusher-js
- 注册pusher 服务
- 地址
- 配置
- .env 配置 pusher相关参数
- config/app.php 注册App\Providers\BroadcastServiceProvider::class,
- resources/assets/js/bootstrap.js 去掉关于Pusher相关的注释 && 填写相关的配置信息
- 注册Broadcast Event源码
- 注意channel是private
- MessageModel中绑定$dispatchesEvents属性,自动触发事件
- Defining Authorization Callbacks
Broadcast::channel('message-to-created.{user_id}', function($user, $user_id){return (int)$user_id === (int) $user->id;});
- 监听channel
- 在需要的组件中定义 源码
效果
效果在线查看
监听private channel
mounted: function () {
// 监听channel
this.listenMessageChannel();
// 初始化列表
this.requestMessage();
},
methods: {
listenMessageChannel : function(){
let vm = this;
window.Echo.private('message-to-created.' + window.Laravel.user_id).listen('MessageCreateEvent', function(e){
let message = e.message;
message.from_user = e.from_user;
vm.list_message.unshift(e.message);
});
},
}
注册Broadcast Event源码
register broadcast
<?php
namespace App\Events;
use App\Message;
use Illuminate\Broadcasting\Channel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class MessageCreateEvent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $from_user;
public $message;
public $broadcastQueue = 'private-message-to-created';
public function broadcastWhen()
{
return $this->message->user_id == $this->message->to_user_id;
}
/**
* Create a new event instance.
*
* @param Message $message
*/
public function __construct(Message $message)
{
$this->message = $message;
$this->from_user = $this->message->fromUser;
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
$private_counter_channel = new PrivateChannel('message-to-counter.' . $this->message->user_id);
$private_created_channel = new PrivateChannel('message-to-created.' . $this->message->user_id);
return [
$private_counter_channel,
$private_created_channel
];
}
}