当前位置: 首页 > 工具软件 > Pusher-js > 使用案例 >

Laravel 使用 laravel-echo 和 pusher-js 实现 WebSocket 广播

谷梁晟
2023-12-01

后端配置使用

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();
			},
		});
	});
 类似资料: