Needed some time to get back to this problem, but now I found a answer with minimum overwriting of vendor code.
The files of interest are below the Channels folder:
|-- laravel-websockets
| |-- src
| | |-- WebSockets
| | | |-- Channels
| | | | |-- ChannelManagers
| | | | |-- ArrayChannelManager.php
| | | |-- Channel.php
| | | |-- ChannelManager.php
| | | |-- PresenceChannel.php
| | | |-- PrivateChannel.php
In the Channel.php, PresenceChannel.php and PrivateChannel.php all pusher server relevant events are handled. Like, subscribing and sending messages. The class ArrayChannelManager controls what class is used for PrivateChannel, PresenceChannel, and Channel.
Laravel-websockets gives you the possibility to use your own channel manager for your project, specified in /config/websockets.php -> 'channel_manager'.
To add Laravel events to pusher server events I overloaded ArrayChannelManager and PrivateChannel (you can overload the others Channels too if needed) and added Laravels queued events. In /config/websockets.php I used my overloaded class as channel_manager.
/config/websockets.php:
'channel_manager' => \App\Lib\Overwrite\LaravelWebsockets\ArrayChannelManager::class,
My overloaded 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;
}
};
In my overloaded PrivateChannel file I hook a MyPusherLaravelEvent to the pusher subscribe event:
<?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);
}
}
Its important to use Laravels queued events to separate the event handling from the pusher server. https://laravel.com/docs/8.x/events#queued-event-listeners
You can also hook your events to the Channel::broadcast... functions and then parse the content to react on certain client commands with your server.
Overload the functions in a generic way, so the vendor code can be updated without you breaking it with your overloads.