需要一些时间来解决这个问题,但现在我找到了一个最小覆盖供应商代码的答案。
感兴趣的文件位于 Channels 文件夹下:
|-- laravel-websockets
| |-- src
| | |-- WebSockets
| | | |-- Channels
| | | | |-- ChannelManagers
| | | | |-- ArrayChannelManager.php
| | | |-- Channel.php
| | | |-- ChannelManager.php
| | | |-- PresenceChannel.php
| | | |-- PrivateChannel.php
在Channel.php、PresenceChannel.php 和PrivateChannel.php 中处理所有推送服务器相关事件。喜欢,订阅和发送消息。 ArrayChannelManager 类控制用于 PrivateChannel、PresenceChannel 和 Channel 的类。
Laravel-websockets 让您可以为您的项目使用自己的频道管理器,在 /config/websockets.php -> 'channel_manager' 中指定。
为了将 Laravel 事件添加到推送服务器事件中,我重载了 ArrayChannelManager 和 PrivateChannel(如果需要,您也可以重载其他通道)并添加 Laravel 排队事件。在/config/websockets.php 中,我使用我的重载类作为channel_manager。
/config/websockets.php:
'channel_manager' => \App\Lib\Overwrite\LaravelWebsockets\ArrayChannelManager::class,
我重载的 ArrayChannelManager:
<?php
namespace App\Lib\Overwrite\LaravelWebsockets;
use BeyondCode\LaravelWebSockets\WebSockets\Channels\Channel;
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManagers\ArrayChannelManager as ArrayChannelManagerBase;
use BeyondCode\LaravelWebSockets\WebSockets\Channels\PresenceChannel;
use App\Lib\Overwrite\LaravelWebsockets\PrivateChannel;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Ratchet\ConnectionInterface;
class ArrayChannelManager extends ArrayChannelManagerBase
{
protected function determineChannelClass(string $channelName): string
{
if (Str::startsWith($channelName, 'private-')) {
return PrivateChannel::class;
}
if (Str::startsWith($channelName, 'presence-')) {
return PresenceChannel::class;
}
return Channel::class;
}
};
在我重载的PrivateChannel 文件中,我将MyPusherLaravelEvent 挂钩到推送订阅事件:
<?php
namespace App\Lib\Overwrite\LaravelWebsockets;
use BeyondCode\LaravelWebSockets\WebSockets\Channels\PrivateChannel as PrivateChannelBase;
use Ratchet\ConnectionInterface;
use stdClass;
class PrivateChannel extends PrivateChannelBase
{
public function subscribe(ConnectionInterface $connection, stdClass $payload)
{
parent::subscribe($connection, $payload);
\App\Events\MyPusherLaravelEvent::dispatch($this->channelName);
}
}
使用 Laravel 队列事件将事件处理与推送服务器分开很重要。 https://laravel.com/docs/8.x/events#queued-event-listeners
您还可以将您的事件挂钩到 Channel::broadcast... 函数,然后解析内容以对您的服务器的某些客户端命令作出反应。
以通用方式重载函数,因此可以更新供应商代码,而不会因重载而破坏它。