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() 方法定义了事件的名称,前端将通过这个名称监听事件。

Get笔记
Get笔记

Get笔记,一款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 客户端的订阅逻辑是成功的关键。

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

1769

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

1184

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

1081

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

948

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

1396

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

1228

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1439

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1303

2023.11.13

ip地址修改教程大全
ip地址修改教程大全

本专题整合了ip地址修改教程大全,阅读下面的文章自行寻找合适的解决教程。

27

2025.12.26

热门下载

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

精品课程

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

共137课时 | 8万人学习

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

共6课时 | 6.9万人学习

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

共13课时 | 0.8万人学习

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

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