0

0

Laravel 与 React 实时通知集成:基于 Pusher 的事件广播教程

心靈之曲

心靈之曲

发布时间:2025-10-10 13:37:25

|

828人浏览过

|

来源于php中文网

原创

laravel 与 react 实时通知集成:基于 pusher 的事件广播教程

本文旨在指导开发者如何在 Laravel 后端与 React 前端之间实现实时通知功能。我们将重点介绍如何利用 Pusher 这一实时事件广播服务,从 Laravel 后端发送通知,并在 React 应用中实时接收并处理这些通知,从而有效解决传统 Web Push API 配置复杂及 self 全局变量报错等常见问题,构建流畅的用户体验。

理解实时通知的挑战与解决方案

在 Web 应用中实现实时通知,尤其是从后端向前端推送信息,是提升用户体验的关键一环。传统的 HTTP 请求-响应模型无法满足实时性需求。对于 Laravel 和 React 这样的前后端分离架构,常见的实时通信方案包括 WebSockets、Server-Sent Events (SSE) 或第三方实时服务(如 Pusher、Ably)。

原始问题中尝试通过 Laravel 的 Notification 组件结合 React 的 Service Worker 来实现 Web Push 通知。虽然 Service Worker 能够实现原生的 Web Push 通知,但其配置相对复杂,需要处理订阅管理、VAPID 密钥生成、消息加密等一系列步骤。此外,Service Worker 中的 self.addEventListener('push') 事件监听器只有在符合 Web Push 协议的消息被推送时才会触发,并且在开发环境中,self 全局变量在某些 linting 规则下可能会被标记为 no-restricted-globals 错误,这通常是由于 Service Worker 文件被当作普通 JavaScript 文件处理,或者在非 Service Worker 上下文中使用 self 导致的。

为了简化实时通知的实现,并绕过 Web Push 的复杂性以及 Service Worker 相关的潜在问题,使用像 Pusher 这样的实时事件广播服务是一个更高效且易于管理的选择。Pusher 提供了一个基于 WebSocket 的抽象层,允许后端轻松广播事件,前端则通过订阅频道来实时接收这些事件。

核心解决方案:Pusher 事件广播

Pusher 是一个托管的实时 API,它允许开发者轻松地在 Web 和移动应用中构建实时功能。Laravel 框架原生支持事件广播,并提供了与 Pusher 集成的便捷方式。通过 Pusher,我们可以定义一个事件,在 Laravel 后端触发它,然后 Pusher 会将该事件广播到所有订阅了相应频道的客户端(React 应用)。

Laravel 后端配置

首先,我们需要在 Laravel 应用中安装并配置 Pusher。

1. 安装 Pusher 依赖

使用 Composer 安装 Pusher PHP SDK:

composer require pusher/pusher-php-server

2. 配置广播驱动

确保在 .env 文件中设置了广播驱动为 pusher,并配置 Pusher 的相关凭据。这些凭据可以在 Pusher 仪表盘中获取。

BROADCAST_DRIVER=pusher
PUSHER_APP_ID=your-pusher-app-id
PUSHER_APP_KEY=your-pusher-app-key
PUSHER_APP_SECRET=your-pusher-app-secret
PUSHER_APP_CLUSTER=your-pusher-app-cluster # 例如:ap2, mt1, eu

在 config/broadcasting.php 文件中,确认 Pusher 驱动已正确配置:

'connections' => [
    '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, // 建议开启加密
        ],
    ],
    // ... 其他广播驱动
],

3. 创建并广播事件

创建一个 Laravel 事件,该事件将实现 ShouldBroadcast 接口。这个接口会告诉 Laravel,该事件应该被广播。

php artisan make:event PushDemoEvent

编辑 app/Events/PushDemoEvent.php 文件:

title = $title;
        $this->message = $message;
        $this->icon = $icon;
        $this->actions = $actions;
    }

    /**
     * 获取事件应该广播到的频道。
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        // 这里定义事件广播到的公共频道。
        // 如果是私有频道,可以使用 PrivateChannel
        return new Channel('notifyChannel');
    }

    /**
     * 获取事件的广播名称。
     * 默认情况下,事件的类名被用作广播名称。
     * 如果你需要自定义,可以重写此方法。
     *
     * @return string
     */
    public function broadcastAs()
    {
        return 'notifyEvent'; // 自定义事件名称
    }
}

请注意,broadcastOn() 方法返回 new Channel('notifyChannel') 定义了一个公共频道。broadcastAs() 方法定义了事件的名称,前端将通过这个名称监听事件。

Grokipedia
Grokipedia

xAI推出的AI在线百科全书

下载

4. 在控制器中触发事件

在你的控制器(例如 PushController)中,当需要发送通知时,分发这个事件。

 'view', 'title' => '查看'],
        ];

        // 触发事件,Laravel 会通过 Pusher 将其广播
        event(new PushDemoEvent($title, $message, $icon, $actions));

        return response()->json(['status' => 'Notification sent via Pusher']);
    }

    // ... 其他方法
}

现在,当 pushNotification 方法被调用时,PushDemoEvent 将会被分发,并通过 Pusher 广播到 notifyChannel 频道,事件名为 notifyEvent。

React 前端集成

在 React 应用中,我们需要安装 Pusher JavaScript 客户端,然后订阅 Laravel 广播的频道并监听事件。

1. 安装 Pusher JS 客户端

在 React 项目中安装 pusher-js

npm install --save pusher-js
# 或者
yarn add pusher-js

2. 初始化 Pusher 实例并订阅频道

在你的 React 组件中,使用 useEffect 钩子来初始化 Pusher 客户端,订阅频道,并绑定事件监听器。

import React, { useEffect, useState } from 'react';
import Pusher from 'pusher-js';

function NotificationComponent() {
  const [notifications, setNotifications] = useState([]);

  useEffect(() => {
    // 确保在组件卸载时清理 Pusher 连接
    let pusher = null;
    let channel = null;

    try {
      pusher = new Pusher(process.env.REACT_APP_PUSHER_APP_KEY, {
        cluster: process.env.REACT_APP_PUSHER_APP_CLUSTER,
        encrypted: true, // 保持与后端配置一致
      });

      channel = pusher.subscribe("notifyChannel");

      channel.bind("notifyEvent", function (data) {
        console.log("Received notification:", data);
        // 在这里处理接收到的通知数据
        // 例如:显示一个弹窗,更新状态,或者使用浏览器 Notification API
        setNotifications(prevNotifications => [...prevNotifications, data]);
        alert(`新通知: ${data.title} - ${data.message}`);

        // 如果想使用浏览器原生通知(与Service Worker不同,这是通过JS触发的)
        if (Notification.permission === 'granted') {
          new Notification(data.title, {
            body: data.message,
            icon: data.icon,
            actions: data.actions
          });
        } else if (Notification.permission !== 'denied') {
          Notification.requestPermission().then(permission => {
            if (permission === 'granted') {
              new Notification(data.title, {
                body: data.message,
                icon: data.icon,
                actions: data.actions
              });
            }
          });
        }
      });

      // 绑定成功订阅的事件(可选)
      channel.bind('pusher:subscription_succeeded', () => {
        console.log('Successfully subscribed to notifyChannel');
      });

    } catch (error) {
      console.error("Pusher initialization failed:", error);
    }

    // 清理函数:在组件卸载时取消订阅并断开 Pusher 连接
    return () => {
      if (channel) {
        channel.unbind_all(); // 解绑所有事件
        pusher.unsubscribe("notifyChannel"); // 取消订阅频道
      }
      if (pusher) {
        pusher.disconnect(); // 断开 Pusher 连接
      }
    };
  }, []); // 空依赖数组表示只在组件挂载和卸载时运行

  return (
    

实时通知

{notifications.length === 0 ? (

暂无新通知。

) : (
    {notifications.map((notif, index) => (
  • {notif.title}: {notif.message}
  • ))}
)}
); } export default NotificationComponent;

注意事项:

  • process.env.REACT_APP_PUSHER_APP_KEY 和 process.env.REACT_APP_PUSHER_APP_CLUSTER 是从环境变量中获取 Pusher 凭据的示例。在实际项目中,你需要在 .env 文件中定义这些变量(例如 REACT_APP_PUSHER_APP_KEY=your-key),React 应用会自动加载它们。
  • pusher.subscribe("notifyChannel") 订阅的频道名称必须与 Laravel 后端 broadcastOn() 方法中返回的频道名称一致。
  • channel.bind("notifyEvent", ...) 监听的事件名称必须与 Laravel 后端 broadcastAs() 方法中定义的事件名称一致(如果 broadcastAs() 被重写,否则默认是事件类名)。
  • useEffect 的清理函数非常重要,它确保在组件卸载时正确地断开 Pusher 连接并取消订阅,防止内存泄漏和不必要的网络请求。

关于 Service Worker 与 self 错误

原始问题中提及的 self.addEventListener('push') 和 unexpected use of 'self' no restricted-globals 错误,主要涉及 Web Push API 和 Service Worker 的使用。

  1. self 错误: self 是 Service Worker 的全局作用域对象,类似于浏览器窗口中的 window。no-restricted-globals 错误通常是 ESLint 或其他 linter 工具的警告,它可能认为你在非 Service Worker 上下文(如普通前端 JavaScript 文件)中使用了 self,或者在 Service Worker 文件中,由于某些配置,它被视为不安全的全局变量。要解决这个 linter 错误,通常需要在 ESLint 配置中为 Service Worker 文件指定正确的环境(如 worker 或 serviceworker),或者禁用相应的规则。
  2. Service Worker push 事件未触发: 即使 self 错误被解决,self.addEventListener('push') 未触发通常意味着后端没有按照 Web Push 协议正确地发送推送消息。Laravel 的 Notification 组件虽然可以用于发送 Web Push 通知(通过 NotificationChannels\WebPush 等包),但它需要一套完整的配置,包括用户订阅、VAPID 密钥管理等。如果这些配置不完整或消息格式不正确,Service Worker 就不会收到 push 事件。

使用 Pusher 的优势在于,它完全绕过了 Web Push API 的复杂性。 Pusher 是基于 WebSocket 的实时通信,它不需要 Service Worker 来接收应用内部的实时事件。前端直接通过 WebSocket 连接到 Pusher 服务器,实时接收事件。这使得实现应用内的实时通知变得更加简单和可靠,特别是对于那些不需要在浏览器关闭时也能接收通知的场景。

注意事项与最佳实践

  1. Pusher Key 安全性: 永远不要将 Pusher 的 APP_SECRET 暴露在前端代码中。只有 APP_KEY 和 APP_CLUSTER 可以在前端使用。
  2. 错误处理: 在 Pusher 客户端初始化和事件绑定时,添加适当的错误处理机制,例如 try-catch 块。
  3. 用户体验: 收到通知后,不仅仅是 alert(),更应该考虑如何以非侵入式的方式向用户展示通知,例如使用 Toast 提示、更新通知中心图标、或显示在页面顶部的横幅。
  4. 授权频道(Private Channels): 如果你的通知需要针对特定用户发送,或者包含敏感信息,你应该使用 Pusher 的授权频道(Private Channels)。这需要在 Laravel 后端实现一个授权路由,Pusher 客户端在订阅私有频道前会向该路由发送请求进行身份验证。
  5. 离线处理: Pusher 主要处理实时在线通知。如果用户离线,他们将不会收到实时事件。对于离线通知,仍然可能需要结合传统的 Web Push API 或其他机制(如消息队列和邮件/短信通知)。
  6. 替代方案: 除了 Pusher,你也可以考虑使用其他实时服务(如 Ably)或自建 WebSocket 服务器(如使用 Laravel Echo Server 结合 Redis 或 Socket.io)。Pusher 的优势在于其托管服务和与 Laravel 的良好集成。

总结

通过将 Laravel 的事件广播系统与 Pusher 实时服务相结合,我们可以高效且可靠地实现从后端到前端的实时通知功能。这种方法简化了开发流程,避免了 Web Push API 的复杂性以及 Service Worker 相关的潜在问题,为 React 应用提供了流畅的实时用户体验。正确配置 Laravel 事件、Pusher 凭据以及 React 客户端的订阅逻辑是成功的关键。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
laravel组件介绍
laravel组件介绍

laravel 提供了丰富的组件,包括身份验证、模板引擎、缓存、命令行工具、数据库交互、对象关系映射器、事件处理、文件操作、电子邮件发送、队列管理和数据验证。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

320

2024.04.09

laravel中间件介绍
laravel中间件介绍

laravel 中间件分为五种类型:全局、路由、组、终止和自定。想了解更多laravel中间件的相关内容,可以阅读本专题下面的文章。

278

2024.04.09

laravel使用的设计模式有哪些
laravel使用的设计模式有哪些

laravel使用的设计模式有:1、单例模式;2、工厂方法模式;3、建造者模式;4、适配器模式;5、装饰器模式;6、策略模式;7、观察者模式。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

373

2024.04.09

thinkphp和laravel哪个简单
thinkphp和laravel哪个简单

对于初学者来说,laravel 的入门门槛较低,更易上手,原因包括:1. 更简单的安装和配置;2. 丰富的文档和社区支持;3. 简洁易懂的语法和 api;4. 平缓的学习曲线。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

374

2024.04.10

laravel入门教程
laravel入门教程

本专题整合了laravel入门教程,想了解更多详细内容,请阅读专题下面的文章。

86

2025.08.05

laravel实战教程
laravel实战教程

本专题整合了laravel实战教程,阅读专题下面的文章了解更多详细内容。

65

2025.08.05

laravel面试题
laravel面试题

本专题整合了laravel面试题相关内容,阅读专题下面的文章了解更多详细内容。

68

2025.08.05

composer是什么插件
composer是什么插件

Composer是一个PHP的依赖管理工具,它可以帮助开发者在PHP项目中管理和安装依赖的库文件。Composer通过一个中央化的存储库来管理所有的依赖库文件,这个存储库包含了各种可用的依赖库的信息和版本信息。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

154

2023.12.25

C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

0

2026.01.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 10.2万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 11.2万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号