Jump24——Laravel 开发人员,精准到位。绝不外包。绝不离岸外包。始终卓越。

使用 Laravel、Livewire 和 Reverb 构建多人扫雷游戏

发布日期 经过

使用 Laravel、Livewire 和 Reverb 构建多人扫雷游戏

大约 20 年前,我第一次尝试编写 PHP 来开发 Web 程序。WordPress、Joomla、Drupal、Zend,只要你能想到的,我可能都用它开发过一些东西。

大约十年前,我放弃了所有这些职业,转而涉足 Ruby、JS、TypeScript 和最近的 Rust 领域。然而,最近关于 PHP 的讨论引起了我的兴趣。我想看看事情的发展。读者,我有福了。即使需要花点时间(阅读文档和处理配置)才能到达棒棒糖的中心。

我学习新事物的策略通常是选择一个愚蠢的项目,然后尽一切努力让它成功。对于我希望发生的事情,我会有一两个硬性要求,其余的都是可塑的。

这是我最终构建的令人愉悦的小应用程序。这是一款多人扫雷 Laravel 应用程序,带有 Livewire、Reverb 并托管在 Fly.io 上。

您可以在这里玩 https://multiplayerminesweeper.lol/ 如果您愿意(打开几个标签并与自己分享链接以获得“多人游戏”体验)。 我有两个不可商榷的硬性要求:第一,我希望能够轻松地与几个朋友在网络上相当大的(至少 20x20)网格上玩扫雷游戏。第二,我不想编写任何 React / Vue 或任何东西。如果有必要,使用一点 javascript 是可以的,但我希望尽可能避免它。

我很高兴地说,任务完成了。可玩网格在 40x40 以内运行良好。事实证明,这需要很长时间才能解决,而 30x30 似乎是一个更合理的游戏长度。更重要的是,我几乎没有编写任何前端 javascript 代码。我完全依靠 Laravel 提供的工具的功能。

你可能会问,在传统的请求/响应绑定语言和服务器中,这怎么可能实现呢?我画了一个简短的图表,显示了一个略微简化的流程。

这是一个看似简单的概念。使用 Livewire 组件时,Laravel 会连接一些简单的 JavaScript,当您执行操作时,它会提交“POST”请求,Livewire 组件服务器端会使用该请求在响应中生成并返回新 HTML,然后将其交换到页面中。Livewire 组件会为您管理一些状态,因此来回传递的状态(例如,维护计数器之类的东西)感觉有点像魔术。

然而,这给我留下了一个问题,即单个客户端只有在提交自己的动作,强制更新函数调用并将最新状态修补到其 HTML 中时,才会看到最新的状态。

正是在这里,Websocket 客户端 Laravel Echo 和第一方 Websocket 服务器 Reverb 成为了最大的赢家。我们可以从每个前端客户端订阅 Reverb 服务器,使用提供的 Laravel Echo 中的一小段 JS 来订阅游戏频道。当任何客户端在棋盘上移动时,Laravel 服务器都会通过 Reverb 服务器向所有订阅者广播“更新”消息。然后,每个客户端都会获取最新状态以修补到其 HTML 中。以下是从“查看者”和“玩家”的角度简要介绍的流程。

最初,在更新过程中,我确实遇到了一些有关大负载大小的问题,而且作弊非常容易。事实证明,除非您另行通知,否则 Livewire 会很乐意发送类上的所有属性。我有一个 board 属性是在每次游戏开始时生成的,其中包含所有地雷的位置,以及其他信息,例如范围内是否有地雷(又名:数字方块)。我无意中将此板水合到每次调用时通过线路传输的组件的状态中。只需制作道具 protected 解决了这个问题。最后,实施 gzip 极大地减少了网络上的有效负载,因为每个单元大部分都是重复的 HTML,从约 300Kb 减少到约 12Kb。

就是这样。这就是全部了,我感觉就像有一个小型单页应用程序,可以和几个朋友一起玩 900 个单元格的扫雷游戏,而无需编写任何 Javascript。最棒的是,我相信这一切都可以大大改进。Laravel,特别是 Livewire,有很多巧妙的优化方法。但重要的是,即使不需要成为专家,我的愚蠢项目仍然可以工作。还能更好吗?是的。但在短短几个小时内,我就构建了一个满足我预定义的硬性要求的东西。

我把所有东西都放到 fly.io 上,开始和朋友们一起测试。它完全成功了,但由于有效载荷可能有点大(特别是在我压缩之前),一位地理位置较远的朋友说它可能有点滞后。我尝试将应用程序的实例分布到几个地区,以便更接近玩家,因为 Fly 平台让这变得非常容易。这很有效,但我意识到这会导致一个问题,因为我使用 SQLite 作为我的数据库。游戏只有在玩家被路由到的服务器上启动时才会存在,玩家才能访问它。

我最终使用 Fly 的一个巧妙功能来解决这个问题,即 fly-replay 标头。如果游戏是在另一台服务器上启动的,它允许我动态地将请求从一台没有该游戏状态的服务器路由到有该游戏状态的服务器,而用户对此一无所知。

在最好的情况下,地理位置较近的玩家可以获得更好的体验,因为无需重播/重新路由。在最坏的情况下,对于玩家分布较广的游戏,远离游戏主机的玩家会产生一些延迟,因为我还没有弄清楚如何克服光速的物理原理。然而,至少它将流量路由到 Fly Proxy 后面,而不是可能较弱的客户端连接。

附注:Fly.io 很好心地赞助了这个愚蠢的项目,并给了我一个链接,让任何读到的人都可以 如果他们想自己玩 Fly.io,则可以获得 50 美元的信用额度 。即使您现在不使用他们的平台,您也可以获取积分,而且它们不会过期!

并非全是彩虹和 200

我想说清楚一点……以下都是出于对 Laravel 和生态系统的认可,因为 Laravel 和生态系统已经取得了如此巨大的成就,以至于其尖锐的棱角尤为明显。发展框架和生态系统的过程应该将新的开发人员体验作为基石。这是我作为一名刚接触该框架的开发人员的体验。

作为 Laravel 生态系统的新手,进入这个生态系统充其量是令人迷茫的。框架的灵活性、功能深度和集成产品让新手无从分析。我不太确定是哪一个,或者我是否需要生态系统选项卡下列出的 25 种不同的东西(答案是,是的)。

开始的时候,我曾尝试过几次,想不出该采取什么方法。最后,我得到了一份非常辣的炖菜,来自当地和赛尔的环境。虽然它仍然有点破损,但就像我高中时用过的道奇 Stratus 一样,它完成了任务。

我认为最让我沮丧和放慢脚步的是,没有明确的“这样做才能开始”。有文档,是的,老实说,可能有太多版本的“入门”。这是一场选择你自己的冒险,路径分叉,在某些点汇合,在另一条路上掉下悬崖(我多次删除整个文件夹,试图卸载所有内容并回到全新状态),有一次你最终来到一条小巷,有人向你提供一些药膏(Laravel Herd)来缓解你所有的疼痛,只需几枚银币。

如果我再次这样做,我会更好地了解要去哪里以及我想要什么。但我在这里的经历与安装节点、运行 npx create-next-app@latest 或者安装 ruby​​,运行 gem install rails

当谈到实际功能时,我花了相当多的时间仔细阅读文档,才明白 Livewire 和 Echo 是我所需要的东西,以便在另一个客户端更新时启用诱导 Livewire 更新的模式。但 Echo 随后提到需要 Redis,而另一个名为 Reverb 的东西是可选的,但如果您愿意,可以使用 Pusher 通道来代替?什么是 Reverb、Pusher 通道?我们都知道我最终找到了答案,我需要一个 websocket 代理,而 Reverb 只是 Laravel 提供的第一方代理。

虽然我并不认为阅读文档是一件坏事,而且这是 Laravel 的“并非所有功能都包含,但可用”策略的副作用,但在很多情况下,记录如此多的选项却没有明确的偏好指标,这很痛苦。如果我是专业地深入研究 Laravel,我可能会虔诚地阅读文档,这一切都不会成为问题。但对于试图设置一切的新开发人员来说,所有这些选项加起来就是一层隐藏的复杂性。

为了说明隐藏的复杂性,在文章开头的草图中...你会看到一个由 redis 驱动的队列系统。我花了很长时间才意识到我需要在本地开发中的某个地方运行队列工作器,这不会在正常启动开发服务器时发生。大概有整整一个小时的时间,我只是认为我的代码是错误的。回想起来,呃,但如果没有在 h4 标题下的文档中看到那两句话的小简介,我可能要花很长时间才能意识到这一点。

最后,当谈到在 fly.io 上运送所有东西时,虽然包装集装箱和运输很容易……但使用 Laravel 本身,所有东西都有很多配置,因为它可以灵活地建模架构。你主要依靠自己的设备和经验来弄清楚。由于缺乏必要的 Laravel 特定经验,我主要依靠猜测和与 AI 玩文档电话。

我只是想把 Reverb 放在 /socket 路径。据我所知,这一定是可能的(确实如此)。虽然最终的咒语相当简单,但文档都做出了各种假设,例如 Reverb 将在其自己的子域上运行。即使是预填充的 .env 配置文件说明希望 Laravel 能够在网络内部访问 Redis,而您的客户端需要跨域的 DNS 解析。

重申本节开头的段落。我花时间写这篇文章只是因为我关心。我日常工作中经常说的一句话是“现实有着令人惊讶的细节”(John Salvatier)。当我看到 Laravel 所做的一切和可以做的一切时,我并不惊讶于入门有点复杂。事实是,Laravel 的成长和发展是为了满足那些依赖它来完成实际工作的人的需求,而实际工作是复杂的。我在这里提出的每一件事都可以通过熟练和有指导的手来修剪和照料生态系统的花园来解决。

我印象深刻,炒作是值得的

不管表达了多少痛苦,我仍然很享受这次旅程和整个项目。我明白了为什么 Laravel 越来越受欢迎,我理解了为什么人们喜欢这个生态系统。我欣赏并重视社区正在建设的一切。

我不会在明天的日常工作中放弃所有工具集并转而使用 Laravel,但我也很确定我下一次使用 PHP 的愚蠢构建不会再等十年。

贾里德·肖特照片

Jared 拥有超过二十年的软件工程经验,他把时间花在“一些有趣的项目”上,并且把收集各种爱好当作自己的爱好——所有这些都是为了尽可能多地了解这个世界及其运作方式。

归档于:
立方体

Laravel 时事通讯

加入超过 4 万名开发者的行列,不错过任何新的技巧、教程等内容。

图像
了解软科技

以每小时 20 美元的价格聘请具备人工智能专业知识的 Laravel 开发人员。48 小时内即可开始工作。

访问 Acquaint Softtech
Tinkerwell 徽标

廷克威尔

Laravel 开发者必备的代码运行器。可在本地和生产环境中体验 AI、自动补全和即时反馈功能。

廷克威尔
几天内即可获得 Laravel 代码审查徽标的专家指导

几天内即可获得 Laravel 代码审查方面的专家指导

专家级代码审查!两位拥有 10 年以上 Laravel 开发经验的开发者将为您提供清晰、实用的反馈,帮助团队构建更优质的应用程序。

几天内即可获得 Laravel 代码审查方面的专家指导
PhpStorm 标志

PhpStorm

首选的 PHP IDE,对 Laravel 及其生态系统提供广泛的开箱即用支持。

PhpStorm
Laravel Cloud 标志

Laravel 云

轻松创建和管理服务器,并在几秒钟内部署 Laravel 应用程序。

Laravel 云
了解 Softtech 的标志

了解软科技

Acquaint Softtech 提供 AI 就绪的 Laravel 开发人员,48 小时内即可上手,每月费用为 3000 美元,没有冗长的销售流程,并提供 100% 退款保证。

了解软科技
Kirschbaum 标志

樱桃树

提供创新和稳定性,确保您的Web应用程序取得成功。

樱桃树
Shift 标志

转移

还在运行旧版本的 Laravel?立即实现 Laravel 自动升级和代码现代化,让您的应用程序保持最新状态。

转移
鱼叉:新一代时间跟踪和发票标志

Harpoon:新一代时间跟踪和发票系统

新一代时间跟踪和计费软件,帮助您的机构规划和预测盈利的未来。

Harpoon:新一代时间跟踪和发票系统
Lucky Media 标志

幸运传媒

Get Lucky Now——拥有十余年经验的 Laravel 开发理想之选!

幸运传媒
SaaSykit:Laravel SaaS 入门套件徽标

SaaSykit:Laravel SaaS 入门套件

SaaSykit 是一个多租户 Laravel SaaS 入门套件,包含运行现代 SaaS 所需的所有功能,例如支付、美观的结账界面、管理面板、用户仪表盘、身份验证、现成组件、统计数据、博客、文档等等。

SaaSykit:Laravel SaaS 入门套件
MongoDB 徽标

MongoDB

Enhance your PHP applications with the powerful integration of MongoDB and Laravel, empowering developers to build applications with ease and efficiency. Support transactional, search, analytics and mobile use cases while using the familiar Eloquent APIs. Discover how MongoDB's flexible, modern database can transform your Laravel applications.

MongoDB
PestPHP Intellisense in Laravel VS Code Extension v1.7.0 image

PestPHP Intellisense in Laravel VS Code Extension v1.7.0

阅读文章
Drop in comments for Filament with Commentions image

Drop in comments for Filament with Commentions

阅读文章
Laravel Starter Kits Now Include Toast Notifications image

Laravel Starter Kits Now Include Toast Notifications

阅读文章
Ship AI with Laravel: Stop Your AI Agent from Guessing image

Ship AI with Laravel: Stop Your AI Agent from Guessing

阅读文章
Laravel Cloud Adds Path Blocking to Prevent Bots From Waking Hibernated Apps image

Laravel Cloud Adds Path Blocking to Prevent Bots From Waking Hibernated Apps

阅读文章
Making Laravel MongoDB Operations Idempotent: Safe Retries for Financial Transactions image

Making Laravel MongoDB Operations Idempotent: Safe Retries for Financial Transactions

阅读文章