Skip to content

Commit d7ea654

Browse files
committed
add client provider
1 parent 193eb5e commit d7ea654

File tree

11 files changed

+205
-63
lines changed

11 files changed

+205
-63
lines changed

config/config.php renamed to config/websockets.php

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
use BeyondCode\LaravelWebSockets\ClientProviders\ConfigClientProvider;
4+
35
return [
46

57
/*
@@ -34,27 +36,26 @@
3436
'passphrase' => null
3537
],
3638

37-
/*
38-
* TODO:: add client config
39-
*
40-
* Default: one item in the array with env PUSHER_APP_ID, _KEY, _SECRET
41-
*
42-
* Add notice app id should be numeric
43-
*
44-
* "clients": [
45-
{
46-
"appId": "cbf9b001405e51d4",
47-
"key": "d886dd1900a5911d00996b41638d7026"
48-
"secret":
49-
}
50-
],
51-
`
39+
/**
40+
* This package comes with multi tenancy out of the box. Here you can
41+
* configure the diffente clients that can use the webSockets server.
5242
*
43+
* You should make sure that the app id is numeric.
44+
*/
5345
'clients' => [
54-
...[]
46+
[
47+
'app_id' => env('WEBSOCKETS_APP_ID'),
48+
'app_key' => env('WEBSOCKETS_APP_KEY'),
49+
'app_secret' => env('WEBSOCKETS_APP_SECRET')
50+
],
5551
],
5652

57-
'client_provider' => ConfigProvider
58-
*/
59-
53+
/**
54+
* This class is responsible for finding the clients. The default provider
55+
* will use the clients defined in this config file.
56+
*
57+
* You can create a custom provider by implementing the
58+
* `ClientProvier` interface.
59+
*/
60+
'client_provider' => ConfigClientProvider::class,
6061
];

src/ClientProviders/Client.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
namespace BeyondCode\LaravelWebSockets\ClientProviders;
4+
5+
6+
use BeyondCode\LaravelWebSockets\Exceptions\InvalidClient;
7+
8+
class Client
9+
{
10+
/** @var int */
11+
public $appId;
12+
13+
/** @var string */
14+
public $appKey;
15+
16+
/** @var string */
17+
public $appSecret;
18+
19+
public static function find(string $appKey): ?Client
20+
{
21+
return app(ClientProvider::class)->findClient($appKey);
22+
}
23+
24+
public function __construct($appId, string $appKey, string $appSecret)
25+
{
26+
if (!is_numeric($appId)) {
27+
throw InvalidClient::appIdIsNotNumeric($appId);
28+
}
29+
30+
if ($appKey === '') {
31+
throw InvalidClient::valueIsRequired('appKey', $appId);
32+
}
33+
34+
if ($appSecret === '') {
35+
throw InvalidClient::valueIsRequired('appSecret', $appId);
36+
}
37+
38+
$this->appId = $appId;
39+
40+
$this->appKey = $appKey;
41+
42+
$this->appSecret = $appSecret;
43+
}
44+
45+
46+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace BeyondCode\LaravelWebSockets\ClientProviders;
4+
5+
6+
interface ClientProvider
7+
{
8+
public function findClient(string $appId): ?Client;
9+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace BeyondCode\LaravelWebSockets\ClientProviders;
4+
5+
class ConfigClientProvider implements ClientProvider
6+
{
7+
public function getClients(): array
8+
{
9+
return config('laravel-websockets.clients');
10+
}
11+
12+
public function findClient(string $appKey): ?Client
13+
{
14+
$allClients = collect(config('websockets.clients'));
15+
16+
$client = $allClients->firstWhere('app_key', $appKey);
17+
18+
if (! $client) {
19+
return null;
20+
}
21+
22+
return new Client(
23+
$client['app_id'],
24+
$client['app_key'],
25+
$client['app_secret']
26+
);
27+
}
28+
}

src/Console/StartWebSocketServer.php

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace BeyondCode\LaravelWebSockets\Console;
44

55
use BeyondCode\LaravelWebSockets\Facades\WebSocketRouter;
6+
use BeyondCode\LaravelWebSockets\Server\Logger;
67
use Illuminate\Console\Command;
78
use BeyondCode\LaravelWebSockets\Server\WebSocketServer;
89

@@ -16,30 +17,47 @@ class StartWebSocketServer extends Command
1617

1718
public function handle()
1819
{
19-
// TODO: add an option to not start the echo server
20-
WebSocketRouter::echo();
20+
$this
21+
->configureLogger()
22+
->registerEchoRoutes()
23+
->startWebSocketServer();
24+
}
25+
26+
protected function configureLogger()
27+
{
28+
app()->singleton(Logger::class, function() {
29+
return (new Logger($this->output))
30+
->enable(config('app.debug'))
31+
//TODO: use real option
32+
->verbose($this->hasOption('vvv'));
33+
});
2134

22-
// TODO: add flag for verbose mode, to send more things to console
35+
return $this;
36+
}
37+
38+
protected function registerEchoRoutes()
39+
{
40+
WebSocketRouter::echo();
2341

24-
$websocketServer = $this->createWebsocketServer();
25-
$websocketServer->run();
42+
return $this;
2643
}
2744

28-
protected function createWebsocketServer(): WebSocketServer
45+
protected function startWebSocketServer()
2946
{
3047
$routes = WebSocketRouter::getRoutes();
3148

3249
$loop = LoopFactory::create();
3350

3451
$loop->futureTick(function () {
35-
$this->info('Started the WebSocket server on port '.$this->option('port'));
52+
$this->info("Started the WebSocket server on port {$this->option('port')}");
3653
});
3754

55+
/** 🎩 Start the magic 🎩 */
3856
return (new WebSocketServer($routes))
3957
->setHost($this->option('host'))
4058
->setPort($this->option('port'))
4159
->setConsoleOutput($this->output)
42-
->enableLogging(config('app.debug'))
43-
->setLoop($loop);
60+
->setLoop($loop)
61+
->run();
4462
}
45-
}
63+
}

src/Exceptions/InvalidClient.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace BeyondCode\LaravelWebSockets\Exceptions;
4+
5+
6+
use Exception;
7+
8+
class InvalidClient extends Exception
9+
{
10+
public static function notFound(int $appId)
11+
{
12+
return new static("Could not find client for app id `{$appId}`.");
13+
}
14+
15+
public static function appIdIsNotNumeric($appId)
16+
{
17+
return new static("Invalid app id `{$appId}` found. An app id should be numeric.");
18+
}
19+
20+
public static function valueIsRequired($name, int $appId)
21+
{
22+
return new static("{$name} is required but was empty for app id {$appId}");
23+
}
24+
}

src/LaravelEcho/WebSocket/PusherServer.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace BeyondCode\LaravelWebSockets\LaravelEcho\WebSocket;
44

5+
use BeyondCode\LaravelWebSockets\ClientProviders\Client;
56
use BeyondCode\LaravelWebsockets\LaravelEcho\Pusher\Exceptions\PusherException;
67
use BeyondCode\LaravelWebSockets\LaravelEcho\Pusher\Exceptions\UnknownAppKey;
78
use Exception;
@@ -59,12 +60,11 @@ protected function verifyConnection(ConnectionInterface $connection)
5960
$queryParameters = [];
6061
parse_str($request->getUri()->getQuery(), $queryParameters);
6162

62-
// Todo: Lookup app-id for multi-tenancy support
63-
if ($queryParameters['appKey'] !== config('broadcasting.connections.pusher.key')) {
63+
if (! $client = Client::find($queryParameters['appKey'])) {
6464
throw new UnknownAppKey($queryParameters['appKey']);
6565
}
6666

67-
$connection->appId = config('broadcasting.connections.pusher.app_id');
67+
$connection->appId = $client->appId;
6868
}
6969

7070
protected function establishConnection(ConnectionInterface $connection)

src/LaravelWebSocketsServiceProvider.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace BeyondCode\LaravelWebSockets;
44

5+
use BeyondCode\LaravelWebSockets\ClientProviders\ClientProvider;
56
use Illuminate\Support\ServiceProvider;
67
use BeyondCode\LaravelWebSockets\LaravelEcho\Pusher\Channels\ChannelManager;
78

@@ -10,7 +11,7 @@ class LaravelWebSocketsServiceProvider extends ServiceProvider
1011
public function boot()
1112
{
1213
$this->publishes([
13-
__DIR__.'/../config/config.php' => base_path('config/websockets.php'),
14+
__DIR__.'/../config/websockets.php' => base_path('config/websockets.php'),
1415
], 'config');
1516

1617
$this->commands([
@@ -20,7 +21,7 @@ public function boot()
2021

2122
public function register()
2223
{
23-
$this->mergeConfigFrom(__DIR__.'/../config/config.php', 'websockets');
24+
$this->mergeConfigFrom(__DIR__.'/../config/websockets.php', 'websockets');
2425

2526
$this->app->singleton('websockets.router', function() {
2627
return new Router();
@@ -29,5 +30,9 @@ public function register()
2930
$this->app->singleton(ChannelManager::class, function() {
3031
return new ChannelManager();
3132
});
33+
34+
$this->app->singleton(ClientProvider::class, function() {
35+
return app(config('websockets.client_provider'));
36+
});
3237
}
3338
}

src/Router.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
use Symfony\Component\Routing\Route;
88
use Ratchet\Http\HttpServerInterface;
99
use Symfony\Component\Routing\RouteCollection;
10-
use Ratchet\WebSocket\MessageComponentInterface;
1110
use BeyondCode\LaravelWebSockets\Exceptions\InvalidWebSocketController;
1211

1312
class Router
@@ -82,12 +81,13 @@ public function echo()
8281
protected function wrapAction($action)
8382
{
8483
if (is_subclass_of($action, WebSocketController::class)) {
85-
8684
$app = app($action);
8785

88-
$appThatLogs = new Logger($app);
86+
if (Logger::isEnabled()) {
87+
$app = Logger::decorate($app);
88+
}
8989

90-
return new WsServer($appThatLogs);
90+
return new WsServer($app);
9191
}
9292

9393
return app($action);

0 commit comments

Comments
 (0)