简介
在您的 Laravel 应用程序中使用 WebSockets 和广播时,随着项目的增长,您的 routes/channels.php
文件会很快变得杂乱。因此,有时很难快速了解您已注册的广播频道。
我最近提交了一个拉取请求 (#46248),提议将新的 channel:list
Artisan 命令添加到 Laravel 框架中。该请求已合并,您现在可以从 Laravel 10.2.0 版本开始使用这个新命令。
在这篇简短的文章中,我们将简要介绍该命令的功能、其局限性以及我认为可能使此命令更加有用的未来变化。
广播频道是什么?
如果您还没有熟悉广播频道,您可以查看这里的文档。简单来说,广播频道是可以用来向用户的浏览器发送数据而不需要刷新页面的WebSocket频道。例如,如果您有一个聊天应用,您可以使用WebSocket在发起新消息时在接收者的浏览器上显示消息。
在Laravel中,您可以为广播定义私有频道。这些是通过授权允许只有打算接收的人可以订阅的WebSocket频道。以我们的聊天应用为例,您只会想让聊天中的接收者能够订阅他们所在的聊天频道。您不会希望他们订阅其他聊天的频道,因为这将意味着他们可以查看其他人的消息。
通常,有两种方法可以定义私有频道。第一种是在routes/channels.php
文件中定义频道,如下所示:
Broadcast::channel('orders.{order}', function (User $user, Order $order) {
return $user->id === $order->user_id;
});
或者,您可以使用一个频道类来封装这个逻辑。例如,您可以创建一个类似这样的频道类:
namespace App\Broadcasting;
use App\Models\Order;
use App\Models\User;
class OrderChannel
{
/**
* Authenticate the user's access to the channel.
*/
public function join(User $user, Order $order): array|bool
{
return $user->id === $order->user_id;
}
}
然后,您可以将您的routes/channels.php
文件更新为使用这个频道类。
use App\Broadcasting\OrderChannel;
Broadcast::channel('orders.{order}', OrderChannel::class);
“频道列表”命令
和您可以通过运行php artisan route:list
来获取应用程序路由的概览类似,有时候您可能想快速查看您的应用程序的私有广播频道。
为了做到这一点,您可以运行新的channel:list
Artisan命令。
例如,如果您有已注册的私有频道,命令的输出可能看起来像这样:
如果您没有任何已注册的私有频道,命令的输出可能看起来像这样:
要为广播频道注册授权逻辑,您需要确保已注册了App\Providers\BroadcastServiceProvider
提供商。默认情况下,Laravel带有此提供商,但不会自动注册。为了开始使用私有频道,您需要找到您的config/app.php
文件中提到此提供商的行,并将其取消注释。如果不注册此提供商,您将无法使用私有频道,并且每次尝试授权和加入时都会收到HTTP 404响应。
我不止一次开始了一个新的项目,添加了我的第一个私有频道,然后在我尝试加入私有频道时得到了404错误。几乎在我参与的每个项目中,我都会忘记取消配置文件中的注释并注册提供商。
为了帮我解决这个问题,我在channel:list
命令中添加了一个附加功能。如果未注册App\Providers\BroadcastServiceProvider
,它将抛出一个警告。这将在未来帮助我!
如果您没有提供程序地运行命令,命令输出可能看起来像这样:
局限性
我所知道的这个命令的最明显的局限性在于它只列出私有频道。这意味着您在应用中使用任何公共频道都不会在命令输出中显示。
这是因为公共频道并没有像私有频道那样注册。相反,要向公共频道广播,可以在从事件的方法broadcastOn
返回新的Illuminate\Broadcasting\Channel
类时指定任何您想要的频道名称。例如,要将事件广播到名为public-channel-name-here
的公共频道,您的事件类可能看起来像这样:
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Queue\SerializesModels;
class ServerCreated implements ShouldBroadcast
{
use SerializesModels;
public function broadcastOn(): array
{
return [
new Channel('public-channel-name-here'),
];
}
}
据我所知,如果不在应用程序中爬取并阅读所有发送广播的事件类,那么我认为没有一种简单的方式来检测和列出公开的频道。尤其是如果某些事件使用复杂的逻辑来动态构建频道名称的话。然而,如果有人知道一种更简单的方法来做这件事,我非常愿意听取!
坦率地说,我以前从未参与过使用公共频道的项目。然而,如果你的项目确实使用了公共频道,请记住它们将不会包含在命令输出中。
未来变更
我对于如何改进未来的 channel:list
命令有几个潜在的想法(当然,前提是 Taylor Otwell 和 Laravel 社区认为它们是实用的)。
类似于 route:list
Artisan 命令有多个选项使其成为你的工具库中一个强大的工具,我认为可以为频道列表命令添加一些额外的选项。例如,我想添加一个 --name
选项(或类似项),允许你过滤输出以仅包含以所传选项开头的频道。例如,你可以运行以下命令以查找以单词 "user" 开头的频道
php artisan channel:list --name=user
我还认为在输出中指定频道授权逻辑期望的参数将会很有用。例如,让我们看看这个私有频道
Broadcast::channel('orders.{order}', function (User $user, Order $order) {
return $user->id === $order->user_id;
});
我认为在命令输出中显示 orders.{order}
频道期望传递一个 Order
模型将会很棒。我认为这可以帮助快速了解那些名称含糊且不明显期待哪些参数的频道。
我可能在不久的将来花时间进一步探索这些想法,并提出一些 pull 请求。它们可能不是必需的(或受欢迎的),因此可能会被拒绝,但值得一试!
你认为哪些变更会有用吗?
结论
希望这篇帖子能让你快速了解新的 channel:list
命令以及在您自己的项目中如何使用它。
如果你喜欢阅读这篇文章,我很乐意听到。同样,如果你有任何反馈可以帮助改进未来的一些文章,我也很愿意听到。
你可能还对检查我的超过220页的电子书 "Battle Ready Laravel" 感兴趣,它更深入地讨论了类似的主题。
如果你有兴趣在每次我发布新文章时都获得更新,请随意 订阅我的通讯。
继续构建精彩的东西! 🚀
driesvints 和 sophy 喜欢了这篇文章