1、安装扩展包:
composer require beyondcode/laravel-websockets
2、发布扩展包配置文件及迁移文件
php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="migrations"
3、运行数据库迁移文件
php artisan migrate
4、发布 laravel-websockets 配置文件、
php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="config"
5、安装 pusher 的 php 扩展包 (laravel-websockets 的 api 完全兼容 pusher, 这里需要安装)
composer require pusher/pusher-php-server "~3.0"
6、修改.env 文件中广播程序的驱动为 pusher
BROADCAST_DRIVER=pusher
7、设置 config/broadcasting.php 中 pusher 配置
默认情况下,Laravel 应用程序广播到 WebSocket 服务器时,是将事件信息发送到官方 Pusher 服务器。但是由于
Laravel WebSockets 包附带了自己的 Pusher API 实现,因此我们需要告诉 Laravel
将事件发送到我们自己的服务器。
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'encrypted' => true,
'host' => '127.0.0.1',
'port' => 33001,
'scheme' => 'http'
],
],
8、配置 websockets 应用 config/websockets.php
一般情况下默认即可
9、开启 websocket 服务
php artisan websockets:serve --port=33001
10、开启队列监听
php artisan queue:listen --tries=5
11、将上边两个使用supervisor进程守护
12、设置nginx反向代理以启用wss
server
{
listen 80;
listen 443 ssl http2;
#SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则
ssl_certificate fullchain.pem;
ssl_certificate_key privkey.pem;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
add_header Strict-Transport-Security "max-age=31536000";
error_page 497 https://$host$request_uri;
#SSL-END
# https 下的 wss 反向代理
location /wss/
{
proxy_pass http://127.0.0.1:33001/;#当前服务器的IP
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
}
*****
}
13、生成Event
php artisan make:event OrderNotifyEvent
14、修改刚刚生成的Event文件,在app/Events目录下
<?php
namespace App\Events;
use App\Models\Order;
use Illuminate\Broadcasting\Channel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class OrderNotifyEvent implements ShouldBroadcast
{
/**
* @var Order
*/
private $order;
/**
* Create a new event instance.
*
* @param int $order_id
*/
public function __construct(int $order_id)
{
$order = Order::with('hospital', 'take_delivery', 'goods_order_details.goods')->find($order_id);
$this->order = $order;
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new Channel('order-notify');
}
/**
* 触发事件时返回的数据
*
* @return null|array
*/
public function broadcastWith(): ?array
{
return !is_null($this->order) ? $this->order->toArray() : [];
}
}
15、在需要推送广播的地方调用
broadcast(new \App\Events\OrderNotifyEvent(850));
至此,后端完成
1、安装 laravel-echo 和 pusher-js 依赖
npm install laravel-echo
npm install pusher-js
2、新建 laravel-echo.js 文件
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
/**
* pusher配置
*/
const pusherConfig = {
id: 'mall_pusher',
key: '1e47c980dd2c0eb78b79d03dce5c8dc5',
secret: '008f442bd9cd15b20a07f31d4d3b2ae7',
wsHost: window.location.hostname,
wsPort: 33001,
wsPath: null,
wssPort: 443,
cluster: 'mt1',
forceTLS: location.protocol === 'https:',
broadcaster: 'pusher',
disableStats: true,
enabledTransports: ['ws', 'wss'],
}
if (pusherConfig.forceTLS) {
pusherConfig.wsPath = '/wss';
}
class LaravelEcho {
static instance = null;
constructor() {
this.instance = new Echo({
client: new Pusher(pusherConfig.key, pusherConfig),
broadcaster: pusherConfig.broadcaster
})
}
setToken(token) {
this.instance.options.client.config.auth.headers.Authorization = `Bearer ${token}`
}
removeToken() {
this.instance.options.client.config.auth.headers = {}
}
}
export default new LaravelEcho();
3、在需要使用的地方引入
import LaravelEcho from '../utils/laravel-echo';
LaravelEcho.instance
.channel('order-notify')
.listen('OrderNotifyEvent', (e) => {
if (!e || !e.id) {
return;
}
const h = this.$createElement;
const notify = this.$notify({
title: '有新订单',
message: h('div', [
h('span', `订单编号:${e.order_no},`),
h('a', {
attrs: {
href: 'javascript:void(0);',
},
style: {
color: '#F54B64',
},
}, '点击查看'),
]),
duration: 0,
onClick: () => {
this.order = Object.assign({}, this.order, e);
this.modal.order_notify.show = true;
notify.close();
},
});
});