Laravel 新 WebSocket 服务 Reverb 使用指南

旧篇 => Laravel/Lumen 中使用 Echo + Socket.IO-Client 实现网页即时通讯广播 https://blog.csdn.net/maxsky/article/details/130394420 已过时
与时俱进,Laravel 官方在 2024 年 7 月发布了 laravel/reverb 包的正式版,因为之前使用的 laravel-echo-server 所使用的 socket.io-client 是比较老旧的 2.0 版本(而且是依赖 NodeJS,内存占用高)
所以更新了此博文帮助大家入门 laravel/reverb 的使用

内容与之前博文大同小异,我亦同步更新了 Laravel Echo 客户端的 Demo 供大家参考

laravel/reverb 最低支持框架版本为 Laravel 10.47+ 以及 PHP 8.2,博文发布时 Laravel 10 版本为 10.48.25,此处使用该框架作为示例(截止博文发布,laravel/reverb 未支持 Lumen 框架

安装

执行 composer require laravel/reverb 安装 Reverb 即可

如果遇到网络问题,可参考该博文解决:Composer 2 镜像处理方案

安装成功后在项目根目录运行 php artisan,可以看到 reverb 相关命令表示安装成功

配置

因为在 Laravel 10 中不存在 php artisan install 命令,所以部分工作需要我们手动完成

首先执行

php artisan reverb:install

该命令行会在 Laravel 10 框架中卡住,我们只需要检查下方相关内容是否成功变更后中断执行即可

  1. 检查 config/app.php 文件底部 providers 部分 是否取消注释 // App\Providers\BroadcastServiceProvider::class, 行,如果没有请手动取消,使 BroadcastServiceProvider 类启用;
  2. 检查 config/broadcasting.php 文件 connections 部分是否出现了 reverb 连接内容;
  3. 检查 config 目录中是否出现了 reverb.php 配置文件;
  4. 检查根目录 .env 文件是否新增了 类似 如下内容:
    REVERB_APP_ID=122822
    REVERB_APP_KEY=1vskpuauarymbej0on7d
    REVERB_APP_SECRET=nyk2kyajfnb0h86yrnoh
    REVERB_HOST="localhost"
    REVERB_PORT=8080
    REVERB_SCHEME=httpVITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
    VITE_REVERB_HOST="${REVERB_HOST}"
    VITE_REVERB_PORT="${REVERB_PORT}"
    VITE_REVERB_SCHEME="${REVERB_SCHEME}"
    
    需特别注意在命令执行期间可能造成 .env 中出现连续两个空行的情况,请自行删掉一行

如果上方 项没有问题,可以 中断 reverb:install 命令

因为 Reverb 同样依赖了广播服务,我们需要在 .env 中修改或新增:

BROADCAST_DRIVER=reverb

发送广播

广播由事件组成,也就是说 因为发生了什么事,需要通知给某个人或者直接公布(所有人)

或者这样形容:广播就是喇叭,事件是通过喇叭“吼叫”(通知/发送)出去的。这就是我们需要创建事件的原因

事件

执行下方命令创建事件类 TestEvent

php artisan make:event TestEvent

该命令会在 app/Events 目录下创建 TestEvent 类。目前这个类非常简单,他有一个 broadcastOn 方法,也就是 通知给谁

注意这里默认的通知是一个 PrivateChannel,也就是 私有频道。为了更简单的完成我们的示例,我们将其更改为 Channel,并将中间的字符串更改为 channel-pub(意为公共频道 public)

接着我们再为该类新增 public 修饰符的 $message$broadcastTime 成员变量并修改构造函数,现在代码看起来是这样:

public string $message;
public string $broadcastTime;/*** Create a new event instance.*/
public function __construct(string $message) {$this->message = $message;$this->broadcastTime = Carbon::now()->toDateTimeString();
}

广播

上方我们虽然创建了需要广播的事件,但是这个事件并不会被(通过)广播发出去,因为事件类需要 实现 Illuminate\Contracts\Broadcasting\ShouldBroadcastIlluminate\Contracts\Broadcasting\ShouldBroadcastNow 接口

ShouldBroadcastNow立即广播,而 ShouldBroadcast异步广播。根据需求你也应该知道使用哪一个接口,这里我们首先使用 ShouldBroadcastNow 进行接下来的操作

当前整个类的代码如下:

<?phpnamespace App\Events;use Carbon\Carbon;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;class TestEvent implements ShouldBroadcastNow {use Dispatchable, InteractsWithSockets, SerializesModels;public string $message;public string $broadcastTime;/*** Create a new event instance.*/public function __construct(string $message) {$this->message = $message;$this->broadcastTime = Carbon::now()->toDateTimeString();}/*** Get the channels the event should broadcast on.** @return array<int, Channel>*/public function broadcastOn(): array {return [new Channel('channel-pub'),];}
}

测试发送广播

和旧篇一样,编写一个测试路由即可。为了方便,我们在 routes/web.php 上方新增一个 Get 路由:

Route::get('/test_broadcast', function () {event((new App\Events\TestEvent('测试消息,Hello')));return 'Event broadcasted!';
});

然后继续下面的操作

接收广播

运行 Reverb 服务,在项目根目录执行:php artisan reverb:start --debug,加上 debug 参数便于我们查询运行情况

如果没有问题,你会得到如下提示:

 INFO  Starting server on 0.0.0.0:8080 (localhost).

注意这个 0.0.0.08080 是基于 config/reverb.php 配置文件中的 hostport 决定

你可以在 .env 中配置 REVERB_SERVER_HOSTREVERB_SERVER_PORT 进行更改。该配置主要决定 Reverb 服务的地址和端口

下方提供两种方式进行测试,大家可以选择自己方便的一种即可

WebSocket 测试软件

例如 Postman、Apifox 等,这里以 Apifox 为例

在 Apifox 中新建 WebSocket 接口,接口地址填入 ws://127.0.0.1:8080/app/REVERB_APP_KEY。注意把 REVERB_APP_KEY 替换为你 .env 文件中对应值,8080 端口对应 REVERB_SERVER_HOST

这里 127.0.0.1 似乎不能用 localhost 代替

填入地址后点击 连接,如果没有问题将得到下方结果:

{"event": "pusher:connection_established","data": "{\"socket_id\":\"676776035.185533755\",\"activity_timeout\":30}"
}

接着在消息中填入下方内容并点击 发送

{"event": "pusher:subscribe","data": {"auth": "","channel": "channel-pub"}
}

得到订阅成功通知:

{"event": "pusher_internal:subscription_succeeded","data": "{}","channel": "channel-pub"
}

此时可以打开浏览器请求你项目的路由 /test_broadcast,浏览器会显示 Event broadcasted! 表明广播已发送。

注意如果连接断开,重新连接并重新发送消息订阅即可

如果没有问题,你会收到类似下方广播内容表明接收成功:

{"event": "App\\Events\\TestEvent","data":"{\"message\":\"\中\文\测\试\",\"broadcastTime\":\"2025-01-08 03:05:20\"}","channel": "channel-pub"
}

Laravel-Echo-Client-Demo

这是一个前端 Demo 便于调试,地址:https://github.com/maxsky/Laravel-Echo-Client-Demo

通过 git 命令 clone 到本地后按 README.md 操作即可

在浏览器中运行该项目,然后请求 /test_broadcast 路由将会得到类似下方结果:

WebSocket 消息测试
你也可以多次请求,网页内容不会清空:

WebSocket 客户端消息 Demo
以上就是即时广播的收发

异步广播

前文有提到,ShouldBroadcastNow立即广播,而 ShouldBroadcast异步广播。异步广播依赖 Redis 队列,所以在 .env 中需要配置好 Redis 连接以及修改 QUEUE_CONNECTION 配置为 redis

队列名

队列名在事件类中指定,我们在 TestEvent 类中添加下方内容:

public string $queue = 'broadcast';

在未指定的情况下,事件会存入 default 默认队列

此时新开命令窗口,在项目根目录下执行:

php artisan queue:work --queue=broadcast

随后浏览器中刷新请求 /test_broadcast 测试路由。有没有发现一个有趣的事,接收到的消息变成了:

{"queue": "broadcast","message": "测试消息,Hello","broadcastTime": "2025-01-08 03:21:28"
}

没错,默认情况下 消息会将所有 public 成员变量广播出去,让我们接着修改

指定广播内容

TestEvent 类中新增 broadcastWith 方法指定广播内容,经过一系列的修改,现在事件类看起来是这样:

<?phpnamespace App\Events;use Carbon\Carbon;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;class TestEvent implements ShouldBroadcast {use Dispatchable, InteractsWithSockets, SerializesModels;public string $queue = 'broadcast';public string $message;public string $broadcastTime;/*** Create a new event instance.*/public function __construct(string $message) {$this->message = $message;$this->broadcastTime = Carbon::now()->toDateTimeString();}/*** Get the channels the event should broadcast on.** @return array<int, Channel>*/public function broadcastOn(): array {return [new Channel('channel-pub'),];}/*** @return array*/public function broadcastWith(): array {return ['name' => 'MyTestEvent','message' => $this->message,'broadcastTime' => $this->broadcastTime];}
}

可以注意到我们在 broadcastWith 中手动指定了返回内容,我们 重新启动队列(修改事件后队列需要重启才会生效)并再次请求 /test_broadcast 路由:

在这里插入图片描述

我们成功过滤了 queue 成员变量,这保障了我们的隐私信息不会暴露出去

最后

Laravel Reverb 简化了操作和授权,具体的授权可参阅官方文档

熟悉之前 Socket.IO-Client 方式的小伙伴能更快上手,美中不足的是现在官方还未支持 Lumen 框架

此外在 Laravel-Echo-Client-Demojs/app.js 代码内有相关说明,需要修改对应的 REVERB_APP_KEY 之类才可成功连接到 Reverb 服务

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/66538.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网工考试下午题目笔记

1、在防火墙设备中&#xff0c;配置双出口链路有提高总带宽、链路负载均衡、提高可靠性的作用&#xff0c;通过配置链路聚合提高总带宽&#xff0c;通过配置策略路由提高链路负载均衡 防火墙工作模式有路由模式(防火墙接口配有IP地址)、透明模式(防火墙相当于不存在)、混合模式…

WEB攻防-通用漏洞_文件上传_黑白盒审计流程

目录 前置知识点 Finecms-CMS文件上传 ​编辑 Cuppa-Cms文件上传 Metinfo-CMS 文件上传 前置知识点 思路&#xff1a; 黑盒就是寻找一切存在文件上传的功能应用 1 、个人用户中心是否存在文件上传功能 2 、后台管理系统是否存在文件上传功能 3 、字典目录扫描探针文件上传构…

Agentic RAG 解释

RAG&#xff08;检索增强生成&#xff09;通过提供来自外部知识源的相关背景来帮助提高 LLM 答案的准确性和可靠性。 Agentic RAG 是高级 RAG 版本&#xff0c;它使用 AI 代理来更加自主地行动。 Agentic RAG 执行以下操作 查询理解、分解和重写检索策略选择知识库管理结果综…

apex安装

安装过程复杂曲折&#xff0c;网上说的很多办法&#xff0c;貌似成功了&#xff0c;实际还是没起作用。 先说成功过程&#xff0c;执行下面命令&#xff0c;安装成功&#xff08;当然&#xff0c;前提是你要先配置好编译环境&#xff09;&#xff1a; &#xff08;我的环境&a…

shell-条件判断

目录 一、条件判断 1.按照文件类型进行判断 2.按照文件权限进行判断 3.两个文件之间进行比较 4.两个整数之间进行比较 5.字符串的判断 6.多重条件判断 二、if条件判断 1.单分支if条件语句 2.双分支if条件语句 &#xff08;1&#xff09;判断某文件是否存在 &#x…

基于FPGA的出租车里程时间计费器

基于FPGA的出租车里程时间计费器 功能描述一、系统框图二、verilog代码里程增加模块时间增加模块计算价格模块上板视频演示 总结 功能描述 &#xff08;1&#xff09;&#xff1b;里程计费功能&#xff1a;3公里以内起步价8元&#xff0c;超过3公里后每公里2元&#xff0c;其中…

将数组转换为laravel中的对象

将数组转换为laravel中的对象 在Laravel中&#xff0c;可以通过使用集合&#xff08;Collection&#xff09;来将数组转换为对象。集合是Laravel提供的一个强大的工具&#xff0c;用于处理数组数据。 将数组转换为Laravel中的对象的步骤如下&#xff1a; 首先&#xff0c;确…

jdk8升级JDK21(Springboot2.7.18升级Springboot3.4.0)

目录 背景&#xff1a; 一、maven升级 二、代码改造 2.1 javax替换为jakarta 2.2 swagger2升级swagger3相关更新 2.2.1 新增SpringDocConfig配置类 2.2.2 全局代码更新 2.2.3 全局代码替换&#xff08;普通正则替换&#xff09; 2.3 Mybatis Plus升级 2.4 logback.xm…

AI赋能跨境电商:魔珐科技3D数字人破解出海痛点

跨境出海进入狂飙时代&#xff0c;AI应用正在深度渗透并重塑着跨境电商产业链的每一个环节&#xff0c;迎来了发展的高光时刻。生成式AI时代的大幕拉开&#xff0c;AI工具快速迭代&#xff0c;为跨境电商行业的突破与飞跃带来了无限可能性。 由于跨境电商业务自身特性鲜明&…

【HarmonyOS NEXT】鸿蒙应用实现屏幕录制详解和源码

【HarmonyOS NEXT】鸿蒙应用实现屏幕录制详解和源码 一、前言 官方文档关于屏幕录制的API和示例介绍获取简单和突兀。使用起来会让上手程度变高。所以特意开篇文章&#xff0c;讲解屏幕录制的使用。官方文档参见&#xff1a;使用AVScreenCaptureRecorder录屏写文件(ArkTS) 二…

Ubuntu挂载云盘操作步骤

1. 查看磁盘分区情况 使用 fdisk -l 命令查看当前系统中所有磁盘的分区情况&#xff0c;找到需要挂载的云盘设备&#xff0c;例如/dev/vdc。 2. 创建新分区 使用 fdisk /dev/vdc 命令对云盘进行分区操作&#xff1a; 输入n创建新分区。 输入p选择创建主分区。 输入1指定分区…

stm32u5串口点灯

通过对单个字符输入的拼接暂存&#xff0c;实现对字符串的比较控制灯的亮灭 char buf[32];char temp[32];while (1){printf("start\n\r");memset(temp,0, sizeof(temp));memset(buf,0, sizeof(buf));while(temp[0] !\r){memset(temp,0, sizeof(temp));HAL_UART_Rece…

PHP 5 6 7 8 9 各重要版本开发特性和选择简要说明

PHP开发&#xff0c;所用版本的选型 PHP5.4是最后一个支持纯正32位操作系统的版本&#xff0c;在Winxp下仍可使用。 PHP5.6是php5.x的最后一个稳定版本&#xff0c;时至今天&#xff0c;仍有很多用户网站系统在使用&#xff0c;网上仍有很多学习资料是基于这个版本&#xff0c;…

Xen 虚拟化技术在云计算平台中的应用详解

Xen 虚拟化技术在云计算平台中的应用详解 随着云计算的飞速发展&#xff0c;虚拟化技术成为构建云平台的核心支柱&#xff0c;而 Xen 作为一种高性能、开源的虚拟化技术&#xff0c;被广泛应用于云计算平台中。Xen 凭借其灵活的架构和出色的性能&#xff0c;为众多云服务商提供…

Elixir语言的正则表达式

Elixir语言中的正则表达式 引言 正则表达式是用于匹配文本模式的一种强大工具。在很多编程语言中&#xff0c;正则表达式被广泛应用于字符串的查找、替换和验证。Elixir作为一门现代化的函数式编程语言&#xff0c;也提供了对正则表达式的支持&#xff0c;方便开发者进行复杂…

MATLAB语言的正则表达式

MATLAB 中的正则表达式使用指南 引言 在数据处理和文本分析中&#xff0c;正则表达式是一种强大而灵活的工具。MATLAB 作为一种广泛应用于科学计算和数据分析的编程语言&#xff0c;提供了对正则表达式的支持&#xff0c;使得用户可以方便地进行字符串匹配与处理。本文将深入…

《Java 中 Thread 类的基本用法总结》

在 Java 编程中&#xff0c;Thread类是实现多线程的核心类之一。下面将对Thread类在创建线程、线程中断、线程等待、线程休眠和获取线程实例等方面的基本用法进行总结。 一、线程创建 继承 Thread 类 定义一个类继承自Thread类。重写run方法&#xff0c;run方法中包含了该线程…

Flannel:Kubernetes 网络方案的“轻骑兵”

Flannel&#xff1a;Kubernetes 网络方案的“轻骑兵” 在 Kubernetes 中&#xff0c;网络是连接所有组件的核心。每个 Pod 都需要一个独立的 IP&#xff0c;方便 Pod 间的通信&#xff0c;而 Flannel 正是解决这个问题的经典容器网络插件&#xff08;CNI&#xff09;。它简单、…

Android - NDK:编译可执行程序在android设备上运行

在android开发中&#xff0c;调试时会把C代码直接编译成可执行程序&#xff0c;运行在android设备上以确认其功能是否正常。 1、基于NDK编译可执行文件 2、push到 /data/local/tmp目录下 3、设置权限&#xff0c;执行。 ndk工程中build.gradle设置 groovy plugins {id com.a…

用matlab调用realterm一次性发送16进制数

realterm采用PutString接口进行发送&#xff0c;需要注意的是发送的16进制数前面要加入0x标志。只有这样&#xff0c;realterm才能将输入的字符串识别为16进制数的形式。 另外,PutString函数支持两个参数输入&#xff0c;第一个参数为字符串&#xff0c;第二个参数为发送形式&…