发布于 2026-01-06 9 阅读
0

使用 laravel-websockets 为您的 Laravel 和 Vue 应用添加实时更新

使用 laravel-websockets 为您的 Laravel 和 Vue 应用添加实时更新

本月初,我发布了listpal.co,这是一个待办事项应用,它集成了 WebSocket 功能,这样每个打开列表的用户都能看到其他所有人的更新。这绝对是一次学习经历,也是我第一次真正深入探索 Vue + WebSocket 的结合。借助laravel-websockets包,在新的(或现有的)Laravel 应用中搭建 WebSocket 服务器非常容易。

比起阅读文章,你更喜欢钻研代码? listpal.co 的所有代码都是开源的,托管在我的 GitHub 上,如果你想深入了解其内部运作机制,可以去看看。否则,让我们开始吧:

起飞前

下面我将介绍如何在现有的 Laravel + Vue 应用中配置和集成 laravel-websockets 包。以下步骤假设您已经搭建了一个基本的待办事项应用,其结构类似于以下示例:

示例 Laravel 应用文件结构的代码截图

目前我们只有一个模型(Item.php),一个对应的控制器,一个用于引入 Vue 应用的 Blade 模板(该应用会列出所有商品),以及 web.php 中的一些基本路由。假设在页面加载时,Vue 应用会调用/api/items该模型来填充列表应用,其中包含一个用于向列表中添加新商品的方法axios.post()

筹办活动

事件是 Laravel 的一种解耦代码的方式,它会在应用程序中发生特定事件时触发。

Laravel 的事件提供了一个简单的观察者实现,允许你订阅和监听应用程序中发生的各种事件。事件类通常存储在 `event.class`app/Events目录中,而它们的监听器则存储在 `event.listeners` 目录中app/Listeners

例如,如果您运营一个电商网站,您可能会有一个名为ProductOrdered 的事件,用于在客户从您的商店购买商品时发送电子邮件确认函。与其将这段代码混杂在产品控制器中,不如将其放在这个特定的事件类中,并使其自动触发或使用全局event()方法触发。

我们将创建一个事件,用于在列表中添加项目时触发,因此请在应用程序根目录的控制台中运行以下命令:

php artisan make:event ItemAdded

这会在 app/Events 目录下创建ItemAdded.php文件,暂时不要修改它。在这个演示中,我们将手动触发事件,因此请在 ItemController 的store()方法中添加以下代码。我建议将其放在 return 语句之前:

event(new App\Events\ItemAdded());

关于这次事件还有一些细节,我们稍后会深入探讨,但现在是时候设置我们的 WebSocket 服务器了。

添加和配置 laravel-websockets

Marcel Pociot 和 Freek Van der Herten 开发的laravel-websockets简直令人难以置信。以前需要单独的 Node 服务器运行 laravel-echo-server 或 socket.io 才能实现的功能,现在完全可以用 PHP 完成(而且在这个例子中,甚至可以在同一个 Laravel 应用代码库中完成🤯)。

除此之外,使用它的最大优势在于它可以直接替代 Pusher,并且与 Laravel 完全集成,开箱即用。只需进行极少的配置即可启动并运行服务器,您的应用程序即可开始愉快地发送广播。

从应用根目录运行以下命令将安装软件包、设置必要的迁移并发布配​​置文件:

安装 laravel-websockets 的步骤代码截图

config/websockets.php如果你想看看,可以打开看看,不过这里其实没什么特别需要做的。我们只需要为这个包设置一个 ID、密钥和密钥即可。幸运的是,它会从我们的 .env 文件中的 PUSHER_ 值获取这些值。你可以随意设置这些值,但我建议它们与项目相关一些:

PUSHER_APP_ID=todoappid
PUSHER_APP_KEY=todoapp
PUSHER_APP_SECRET=todoappsecret
Enter fullscreen mode Exit fullscreen mode

保存文件,在终端中导航到项目根目录,然后运行
php artisan websockets:serve✨。我们的 WebSocket 服务器现已启动,等待指令!

返回我们的活动

现在我们的 WebSocket 端口已经启动并运行,我们需要向它提供要广播的数据。Laravel 再次让这一切变得异常简单。如果您打开我们的文件,app/Events/ItemAdded.php您会看到默认类包含了 `WebSocket` 接口Illuminate\Contracts\Broadcasting\ShouldBroadcast。我们可以将此接口实现到我们的类中,使其能够与 Pusher(以及 laravel-websockets)一起使用。

当此事件触发时,该类中设置的任何公共变量都会被广播出去。由于每次添加项目时,我们都希望应用程序使用数据库中的所有项目更新其列表,因此我们将设置一个名为 `items` 的公共变量,$items并在构造函数中填充它。

最后,该broadcastOn()方法将返回我们选择的频道名称,数据将广播到该频道。所有内容组合在一起后应该类似于这样:

Laravel 应用中示例事件的代码截图

至此,我们应用后端所需的修改就全部完成了!现在,让我们开始学习一些 JavaScript 代码。

修改 Vue 前端

如果你使用的是 Laravel 的 Vue 配置,那么你的文件底部很可能有一段被注释掉的部分,bootstrap.js内容如下:

Laravel Echo 在 JavaScript 文件中的代码截图

取消注释整个代码块。这将使我们的应用程序能够使用 Laravel Echo 包,该包将在应用程序启动时进行初始化。它会使用我们在文件中输入的密钥来.env初始化监听 WebSocket 服务器所需的信息。

下一步可能会有点棘手,这取决于你获取数据的方式以及是否使用了像 Vuex 这样的状态管理库。假设你没有使用状态管理库,而是在主 Vue 组件的数据对象中使用数组来存储项目,并在添加项目时调用 axios 方法将数据发送到你的 API。在成功处理过程中,你只需将组件中的数据替换为服务器返回的数据即可。

现在,我们将把 Echo 集成到一个生命周期方法中,并让它监听我们之前指定的通道。当回调函数被触发时,我们会将组件中的数据替换为通过事件广播出去的公共属性。以下是一个设置示例:

示例 Vue 组件(包含 laravel-websockets)的代码截图

🎉 🎉 🎉

这样就无需让我们的 axios 调用访问我们的数据了,一旦我们的新项目添加到服务器,就会触发一个事件,Echo 会处理它。

将所有内容联系起来

再次重申一下,我们已经:

  • 使用默认配置安装了 laravel-websockets 包

  • 启动了 WebSocket 服务器php artisan websockets:serve

  • 添加了一个名为ItemAdded 的事件,该事件实现了 ShouldBroadcast 接口。

  • 在我们的 Laravel 应用程序的 bootstrap.js 文件中添加了 Echo 组件

  • 我们将 Vue 组件中更新数据的方法替换为 Echo 监听器,并移除了 axios 的成功回调。

对我个人而言,这确实为我的项目开启了无限可能。我一直认为任何形式的 WebSocket 功能都会是一项相当庞大的工程,需要额外的框架或独立的服务器实例,但这种方法彻底颠覆了我的想法。

以此为基础,您可以进行扩展,为每个模型或操作(保存、删除、更新)添加不同的事件,或者结合使用 Echo 和 Vuex 来提交 store 中的数据。如果您能够使用 PHP 或在现有的 Laravel 应用中实现这些功能,那么可能性将非常广泛。

如果您想与我联系,有任何疑问,或者对 PHP/Laravel/Vue/通用 Web 开发领域的更多实用技巧感兴趣,欢迎在Twitter上关注我!

文章来源:https://dev.to/aschmelyun/adding-real-time-updates-to-your-laravel-and-vue-apps-with-laravel-websockets-3ac2