使用 Laravel 广播事件实现基于 Socket.io 的实时消息通知
本文将基于
Laravel 5.5 + Vuejs 2.5.2
介绍使用Laravel-echo-server.js
和Laravel-echo.js
实现的 socket 服务
前置条件
开始使用
-
指定事件广播驱动
修改.env
配置项BROADCAST_DRIVER
为redis
-
创建消息通知
确保 User Model 使用了 Notifiable 的 Trait
php artisan make:notification TestNotification
-
编辑
TestNotification
修改
via
方法return ['broadcast']
因为
toArray
会同时被解析到database
, 而我们的通知可能和数据库中的存储不太一样,所以单独使用其broadcast
增加
toBroadcast
方法public function toBroadcast($notifiable) { return new BroadcastMessage([ 'message' => $this->data['message'] ]); }
完整的代码如下
class Test extends Notification implements ShouldQueue { use Queueable; public $data; public function __construct($data = []) { $this->data = $data; } public function via($notifiable) { return ['broadcast']; } public function toBroadcast($notifiable) { return new BroadcastMessage([ 'message' => $this->data['message'] ]); } }
-
安装 socket 服务端
npm install -g laravel-echo-server
安装完成后,在项目根目录执行laravel-echo-server init
生成配置文件 , 具体参考 Laravel-echo-server
最后,生成的文件大概类似:{ "authHost": "http://sickle.dev", "authEndpoint": "/broadcasting/auth", "database": "redis", "databaseConfig": { "redis": { "port" : "6379", "host" : "127.0.0.1", "db" : 5 }, "sqlite": { "databasePath": "/database/laravel-echo-server.sqlite" } }, "devMode": true, "host": null, "port": "6001", "protocol": "http", "socketio": {}, "sslCertPath": "", "sslKeyPath": "", "sslCertChainPath": "", "sslPassphrase": "", "apiOriginAllow": { "allowCors": true, "allowOrigin": "http://localhost:1024", "allowMethods": "GET, POST", "allowHeaders": "Origin, Content-Type, X-Auth-Token, X-Requested-With, Accept, Authorization, X-CSRF-TOKEN, X-Socket-Id" } }
可以参考我的配置,其中 authHost 为你当前项目的域名,allowOrigin 为允许跨域的域名,开发时建议设成 * 号
最后,执行 laravel-echo-server start
开启 socket
服务端
以下为前端部分
- 安装
echo
客户端
为简单起见,我们使用一个第三方 vue
包 vue-echo
在 main.js
里导入这个包
import Echo from 'vue-echo'
if(typeof io === 'function'){
Vue.use(Echo, {
broadcaster: 'socket.io',
host: 'service.dev:6001',// 后端的URL + Laravel-echo-server 配置的端口号
auth:{
headers: {
'Authorization': 'Bearer ' + getToken() // getToken前端自行实现
}
},
});
}
在使用之前,最好将使用
socket
服务作为可选项。
然后,开启监听
if(typeof this.$echo !== 'undefined'){
this.$echo.private(`App.Models.User.${this.user_info.user_id}`) //App.Models.User.1
.notification((notification) => {
if (notification.type === 'App\\Notifications\\TestNotification') {
console.log(notificaition)
let message = notification.message;
let notify = this.$notify({
title: '通知',
dangerouslyUseHTMLString: true,
message: message,
type: 'info',
onClick: () => {
notify.close();
this.$router.push({ name: 'xx' }) // 处理跳转到哪
}
});
}
})
}
如果不出意外,此时,已经可以监听到了。
本作品采用《CC 协议》,转载必须注明作者和本文链接
目前还没用过。不知道用在后台什么功能上面。后面折腾下
太棒了
等等就來測試
还没写完吧?
@839891627 一般来说消息的实时通知应用的最多
@jacktop 最近太忙。。现在补
多谢楼主!
请问下大神,这个方法能在小程序里面用吗?用wepy的话?
@dptms 当然可以
@dptms 小程序参考 wx.connectSocket
@jacobsun
this.$echo.private(
App.Models.User.${this.user_info.user_id})
那这种写法,在小程序里面应该怎么写呢?vue 有use Echo
但是小程序里面的 websocket 跟这个不太一样吧?@dptms 小程序的socket没用过,但是方法应该一样。
自定义一个广播,简单的可以用redis的发布订阅功能,然后自定义一个socket server处理redis的消息,然后小程序里正常连接socket server,最后,注意下channel即可
博主~ ,如果使用 Result API 风格设计的时候,1.该怎样写 2.怎么调试呢?不知道后续你有没有更新呐~
Laravel-echo-server在服务器怎么部署呢?
您好,配置成功了。请问 controller 接口代码 怎么使用,有没有
demo
可以借鉴一下?大神