Laravel 广播与实时通知:用事件 + Redis 通道把订单状态推到前端

test12026-09-241 次阅读

为什么需要服务端主动推送

订单状态变化(已支付、已发货、已签收)如果让前端轮询接口,既浪费连接也做不到实时。Laravel 的广播机制把"事件"通过驱动(常用 Redis + WebSocket 网关)推到前端订阅的频道,浏览器用 Laravel Echo 监听即可,无需自己写长轮询。

定义可广播的事件

事件类实现 ShouldBroadcast 接口,并指定 broadcastOn 返回的频道。Laravel 会在事件被触发(event(...) 或 dispatch)时,把事件载荷序列化后发往配置的广播驱动。

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;

class OrderStatusChanged implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets;

    public function __construct(
        public int $orderId,
        public string $status,
        public string $userId
    ) {}

    public function broadcastOn(): array
    {
        // 每个用户一个私有频道,只有本人能订阅
        return [new Channel("orders.{$this->userId}")];
    }

    public function broadcastWith(): array
    {
        return [
            "order_id" => $this->orderId,
            "status" => $this->status,
            "at" => now()->toIso8601String(),
        ];
    }
}

触发事件

在业务代码里触发即可,其余交给框架。注意私有频道需要前端鉴权,Laravel 自带广播鉴权路由,用 Sanctum/Auth 守卫判断用户是否有权订阅该频道。

<?php

use App\Events\OrderStatusChanged;

// 支付回调里
public function paid(int $orderId, int $userId)
{
    // ...更新订单状态到数据库
    event(new OrderStatusChanged($orderId, "paid", (string) $userId));
}

前端用 Echo 监听

前端引入 laravel-echo 与 socket.io-client,连接 WebSocket 网关(如 Soketi / Pusher),订阅私有频道并监听事件名(默认是事件类短名)。

import Echo from "laravel-echo";
import io from "socket.io-client";

const echo = new Echo({
  broadcaster: "socket.io",
  host: "https://ws.example.com",
  auth: { headers: { Authorization: `Bearer ${token}` } },
});

echo.private(`orders.${userId}`)
  .listen("OrderStatusChanged", (e) => {
    console.log("订单状态更新", e.status, e.order_id);
    // 更新界面提示,无需轮询
  });

配置与部署要点

  • 服务端 .env 设 BROADCAST_DRIVER=redis,并启动一个 WebSocket 网关(Soketi/Pusher 兼容)和队列 worker 处理广播任务。
  • 私有频道需后端暴露 /broadcasting/auth 路由做订阅鉴权,未授权订阅会被拒绝。
  • 生产环境给 WebSocket 网关挂上 TLS 与连接数限制,频道按用户维度隔离,避免越权收到他人事件。
T

test1

文章作者

为什么需要服务端主动推送 订单状态变化(已支付、已发货、已签收)如果让前端轮询接口,既浪费连接也做不到实时。Larav...

分类
技术
发布时间
2026-09-24
字数
约 2041 字
阅读
1 次