Laravel11 从0开发 Swoole-Reverb 扩展包(一) - 扩展包开发
前言
大家好呀,我是yangyang。好久没更新了,最近新项目在使用laravel11(截止目前发文,laravel12也发布了)做开发,自己也是利用有些空闲时间做些除开业务以外的深入学习,因此也就萌生了做一个系列随笔文章的想法。
laravel11
Laravel 11 继续改进 Laravel 10.x,通过引入简化的应用程序结构、每秒速率限制、健康路由、优雅的加密密钥轮换、队列测试改进、Resend 邮件传输、Prompt 验证器集成、新的 Artisan 命令等。此外,Laravel Reverb,一个官方的可扩展 WebSocket 服务器也被引入,为您的应用程序提供强大的实时功能。
————————————————
开篇
laravel Reverb
Laravel Reverb 由 Joe Dixon 开发。Laravel Reverb 为 Laravel 应用程序带来了极速且可扩展的实时 WebSocket 通信,并与 Laravel 现有的事件广播工具(如 Laravel Echo)无缝集成。此外,Reverb 支持通过 Redis 的发布 / 订阅功能进行水平扩展,使您能够将 WebSocket 流量分布在多个后端 Reverb 服务器上,从而支持单个高需求应用程序。
有关 Laravel Reverb 的更多信息,请查阅完整的 Reverb 文档。
开发原由
24年出了一些关于Reverb混响的一些随笔,最近也简单跟踪了下它的源码,laravel无愧于设计大神,Joe Dixon 大佬的封装设计实现非常到位,以至于云里雾里的。Reverb在ws+http混合服务使用的react-php实现,想着国内(个人认知,不代表所有)用它不多,多是swoole、workerman。于是就想到了用swoole来复刻一个版本,一开始,准备基于Reverb来扩展swoole并支持替换react-php。发现代码设计关联很多,我个人难以撼动,于是另辟蹊径,做一个新的扩展包。
因此,在本系列文章中,我将分享如何从零开始为 Laravel11 开发一个自定义扩展包——Swoole-Reverb,目前这个扩展包我也抽空开发,在开发过程中,我遇到了一些问题,如果我觉得有用,我会第一时间总结一些方案,希望能为大家提供一些参考和帮助。最后,也希望能够像到Joe Dixon大神的水准看齐。
一、项目结构和初始设置
首先,我们在 Laravel 应用的同级目录下创建了一个 core
目录,并在其中放置 Swoole-Reverb 扩展包的代码。基本的目录结构如下:
project-root/
├── app/
├── core/
│ └── SwooleReverb/
│ └── src/
│ ├── Providers/
│ │ ├── BroadcastServiceProvider.php
│ │ └── SwooleReverbServiceProvider.php
│ └── Broadcasting/
│ └── SwooleBroadcaster.php
└── composer.json
在主项目的 composer.json
文件中,我们通过 autoload
配置引入了 Swoole-Reverb 的命名空间:
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/",
"SwooleReverb\\": "core/SwooleReverb/src/"
}
}
同时,在 extra
部分配置了 Laravel 的自动发现信息:
"extra": {
"laravel": {
"providers": [
"SwooleReverb\\Providers\\BroadcastServiceProvider",
"SwooleReverb\\Providers\\SwooleReverbServiceProvider"
]
}
}
目前考虑到开发方便,一开始的操作是这样的,后期在做独立包。
注意:自动发现机制只针对通过 Composer 安装到 vendor 目录中的包生效。如果你把包直接放在项目根目录外(比如
core
目录下),Laravel 不会自动发现这些包。解决办法可以是通过 本地路径仓库 将包安装进 vendor 中,或者直接手动注册服务提供者。
二、自动发现问题和手动注册
但是按照我上面的方式,在开发过程中,我发现执行 php artisan vendor:publish
无法找到 Swoole-Reverb 的服务提供者。经过排查,主要原因是 Laravel 自动发现机制不支持直接放在项目根目录的扩展包。
解决方案
- 本地路径仓库方式
在主项目的composer.json
中添加如下配置,将 repositories 改为数组形式并追加本地路径仓库:
然后在"repositories": [ { "type": "composer", "url": "https://packagist.org" }, { "type": "path", "url": "core/SwooleReverb" } ]
core/SwooleReverb
下的composer.json
中配置包的基本信息以及自动发现信息,示例如下:
然后执行:{ "name": "wanzij/swoole-reverb", "autoload": { "psr-4": { "SwooleReverb\\": "src/" } }, "extra": { "laravel": { "providers": [ "SwooleReverb\\Providers\\BroadcastServiceProvider", "SwooleReverb\\Providers\\SwooleReverbServiceProvider" ] } } }
composer require wanzij/swoole-reverb:"dev-main"
提示:最初使用
dev-master
可能会报错,因为包分支名称可能已经从 master 改为了 main。
这个流程就是正确完整的扩展包开发流程。
- 手动注册服务提供者
当然在前期的开发中,我们为了方便,上面的方式更可取,因为不用每次更新代码后,执行composer update
更新,所以如果不想采用本地路径仓库的方式,也可以直接在config/app.php
中手动注册服务提供者:
这样可以确保服务提供者被加载。'providers' => [ // 其他服务提供者... SwooleReverb\Providers\BroadcastServiceProvider::class, SwooleReverb\Providers\SwooleReverbServiceProvider::class, ],
三、开发中的常见问题及解决方案
1. 类找不到或命名空间错误
- 问题:在执行
php artisan vendor:publish
时找不到服务提供者。 - 解决:确认
composer dump-autoload
已执行,检查目录结构和文件顶部的命名空间是否正确。
2. 依赖容器绑定错误
- 问题:使用
$this->app->make('broadcast')
报Target class [broadcast] does not exist.
错误。 - 解决:可以直接使用完整类名
\Illuminate\Broadcasting\BroadcastManager::class
来获取实例,例如:$this->app->make(\Illuminate\Broadcasting\BroadcastManager::class)->extend('swoole', function ($app, $config) { return new SwooleBroadcaster( $config['host'] ?? 'localhost', $config['port'] ?? 8084, $config['options'] ?? [] ); });
3. Composer 版本稳定性问题
- 问题:安装包时提示最低稳定性问题,例如:
Could not find a version of package wanzij/swoole-reverb matching your minimum-stability (stable).
- 解决:
- 显式指定使用开发版:
composer require wanzij/swoole-reverb:"dev-main"
- 或者在主项目
composer.json
中调整最低稳定性:"minimum-stability": "dev", "prefer-stable": true
- 显式指定使用开发版:
四、总结
看完后,我们关心的点又: Laravel 的自动发现机制、 Composer 的本地路径仓库配置以及容器绑定的相关问题。
后续我会继续分享更多关于扩展包开发的细节和实践经验,敬请关注!
如果有任何问题或建议,欢迎在评论区留言讨论。
更多文档参考: