Skip to content

Commit

Permalink
Refactor channels (#17)
Browse files Browse the repository at this point in the history
* slim channel manager

* rename connection manager

* add channel connection manager

* channels manage connections

* Fix code styling
  • Loading branch information
joedixon authored Nov 20, 2023
1 parent c69b7b4 commit b07fa67
Show file tree
Hide file tree
Showing 19 changed files with 252 additions and 237 deletions.
29 changes: 20 additions & 9 deletions src/Channels/Channel.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,23 @@

use Exception;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\App;
use Laravel\Reverb\Application;
use Laravel\Reverb\Contracts\ChannelManager;
use Laravel\Reverb\Contracts\ChannelConnectionManager;
use Laravel\Reverb\Contracts\Connection;
use Laravel\Reverb\Output;

class Channel
{
/**
* The channel connections.
*
* @var \Laravel\Reverb\Contracts\ChannelConnectionManager
*/
protected $connections;

public function __construct(protected string $name)
{
$this->connections = app(ChannelConnectionManager::class);
}

/**
Expand All @@ -24,32 +31,36 @@ public function name(): string
return $this->name;
}

/**
* Get all connections for the channel.
*/
public function connections(): array
{
return $this->connections->all();
}

/**
* Subscribe to the given channel.
*/
public function subscribe(Connection $connection, string $auth = null, string $data = null): void
{
App::make(ChannelManager::class)
->for($connection->app())
->subscribe($this, $connection, $data ? json_decode($data, true) : []);
$this->connections->add($connection, $data ? json_decode($data, true) : []);
}

/**
* Unsubscribe from the given channel.
*/
public function unsubscribe(Connection $connection): void
{
App::make(ChannelManager::class)
->for($connection->app())
->unsubscribe($this, $connection);
$this->connections->remove($connection);
}

/**
* Send a message to all connections subscribed to the channel.
*/
public function broadcast(Application $app, array $payload, Connection $except = null): void
{
collect(App::make(ChannelManager::class)->for($app)->connections($this))
collect($this->connections())
->each(function ($connection) use ($payload, $except) {
if ($except && $except->id() === $connection->id()) {
return;
Expand Down
45 changes: 0 additions & 45 deletions src/Concerns/EnsuresIntegrity.php

This file was deleted.

26 changes: 26 additions & 0 deletions src/Contracts/ChannelConnectionManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Laravel\Reverb\Contracts;

interface ChannelConnectionManager
{
/**
* Add a connection.
*/
public function add(Connection $connection): void;

/**
* Remove a connection.
*/
public function remove(Connection $connection): void;

/**
* Get all the connections.
*/
public function all(): array;

/**
* Flush the channel connection manager.
*/
public function flush(): void;
}
21 changes: 4 additions & 17 deletions src/Contracts/ChannelManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use Illuminate\Support\Collection;
use Laravel\Reverb\Application;
use Laravel\Reverb\Channels\Channel;
use Laravel\Reverb\Managers\Connections;

interface ChannelManager
{
Expand All @@ -19,32 +18,20 @@ public function app(): ?Application;
*/
public function for(Application $application): ChannelManager;

/**
* Subscribe to a channel.
*/
public function subscribe(Channel $channel, Connection $connection, array $data = []): void;

/**
* Unsubscribe from a channel.
*/
public function unsubscribe(Channel $channel, Connection $connection): void;

/**
* Get all the channels.
*/
public function all(): Collection;

/**
* Unsubscribe from all channels.
* Find the given channel
*/
public function unsubscribeFromAll(Connection $connection): void;
public function find(string $channel): Channel;

/**
* Get all connections for the given channel.
*
* @return <array string, \Laravel\Reverb\Connection>
* Unsubscribe from all channels.
*/
public function connections(Channel $channel): array;
public function unsubscribeFromAll(Connection $connection): void;

/**
* Flush the channel manager repository.
Expand Down
4 changes: 2 additions & 2 deletions src/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use Illuminate\Support\Arr;
use Illuminate\Support\Facades\App;
use Laravel\Reverb\Channels\ChannelBroker;
use Laravel\Reverb\Contracts\ChannelManager;
use Laravel\Reverb\Contracts\Connection;
use Laravel\Reverb\Contracts\ServerProvider;

Expand Down Expand Up @@ -38,7 +38,7 @@ public static function dispatchSynchronously(Application $app, array $payload, C

foreach ($channels as $channel) {
unset($payload['channels']);
$channel = ChannelBroker::create($channel);
$channel = app(ChannelManager::class)->find($channel);
$payload['channel'] = $channel->name();

$channel->broadcast($app, $payload, $connection);
Expand Down
48 changes: 48 additions & 0 deletions src/Managers/ArrayChannelConnectionManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace Laravel\Reverb\Managers;

use Laravel\Reverb\Contracts\ChannelConnectionManager;
use Laravel\Reverb\Contracts\Connection;

class ArrayChannelConnectionManager implements ChannelConnectionManager
{
/**
* Connection store.
*
* @var array<string, array<string, \Laravel\Reverb\Connection>>
*/
protected $connections = [];

/**
* Add a connection.
*/
public function add(Connection $connection): void
{
$this->connections[$connection->identifier()] = $connection;
}

/**
* Remove a connection.
*/
public function remove(Connection $connection): void
{
unset($this->connections[$connection->identifier()]);
}

/**
* Get all the connections.
*/
public function all(): array
{
return $this->connections;
}

/**
* Flush the channel connection manager.
*/
public function flush(): void
{
$this->connections = [];
}
}
108 changes: 108 additions & 0 deletions src/Managers/ArrayChannelManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php

namespace Laravel\Reverb\Managers;

use Illuminate\Support\Collection;
use Illuminate\Support\Facades\App;
use Laravel\Reverb\Application;
use Laravel\Reverb\Channels\Channel;
use Laravel\Reverb\Channels\ChannelBroker;
use Laravel\Reverb\Concerns\InteractsWithApplications;
use Laravel\Reverb\Contracts\ApplicationProvider;
use Laravel\Reverb\Contracts\ChannelManager as ChannelManagerInterface;
use Laravel\Reverb\Contracts\Connection;

class ArrayChannelManager implements ChannelManagerInterface
{
use InteractsWithApplications;

/**
* Application store.
*
* @var array<string, array<string, array<string, \Laravel\Reverb\Channels\Channel>>>
*/
protected $applications = [];

/**
* The appliation instance.
*
* @var \Laravel\Reverb\Application
*/
protected $application;

/**
* Get the application instance.
*/
public function app(): ?Application
{
return $this->application;
}

/**
* Get all the channels.
*/
public function all(): Collection
{
return collect($this->channels());
}

/**
* Find the given channel
*/
public function find(string $channel): Channel
{
return $this->channels($channel);
}

/**
* Unsubscribe from all channels.
*/
public function unsubscribeFromAll(Connection $connection): void
{
foreach ($this->channels() as $channel) {
$channel->unsubscribe($connection);
}
}

/**
* Get the given channel.
*/
public function channel(string $channel): array
{
return $this->channels($channel);
}

/**
* Get the channels.
*/
public function channels(string $channel = null): array|Channel
{
if (! isset($this->applications[$this->application->id()])) {
$this->applications[$this->application->id()] = [];
}

$channels = $this->applications[$this->application->id()];

if ($channel) {
if (! isset($channels[$channel])) {
$this->applications[$this->application->id()][$channel] = ChannelBroker::create($channel);
}

return $this->applications[$this->application->id()][$channel];
}

return $channels ?: [];
}

/**
* Flush the channel manager repository.
*/
public function flush(): void
{
App::make(ApplicationProvider::class)
->all()
->each(function (Application $application) {
$this->applications[$application->id()] = [];
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
namespace Laravel\Reverb\Managers;

use Closure;
use Illuminate\Contracts\Cache\Repository;
use Illuminate\Support\Facades\App;
use Laravel\Reverb\Application;
use Laravel\Reverb\Concerns\InteractsWithApplications;
use Laravel\Reverb\Contracts\ApplicationProvider;
use Laravel\Reverb\Contracts\Connection;
use Laravel\Reverb\Contracts\ConnectionManager as ConnectionManagerInterface;

class ConnectionManager implements ConnectionManagerInterface
class ArrayConnectionManager implements ConnectionManagerInterface
{
use InteractsWithApplications;

Expand Down
Loading

0 comments on commit b07fa67

Please sign in to comment.