This commit is contained in:
Marcel Pociot 2018-11-24 23:52:55 +01:00
parent 92362ba918
commit 8faa7bf3f1
13 changed files with 99 additions and 82 deletions

View File

@ -25,10 +25,10 @@
"php": "^7.1",
"ext-json": "*",
"cboden/ratchet": "^0.4.1",
"illuminate/console": "5.6.*|5.7.*",
"illuminate/http": "5.6.*|5.7.*",
"illuminate/routing": "5.6.*|5.7.*",
"illuminate/support": "5.6.*|5.7.*",
"illuminate/console": "5.7.*",
"illuminate/http": "5.7.*",
"illuminate/routing": "5.7.*",
"illuminate/support": "5.7.*",
"symfony/http-kernel": "~4.0",
"symfony/psr-http-message-bridge": "^1.1"
},

View File

@ -1,14 +1,10 @@
<?php
use BeyondCode\LaravelWebSockets\Http\Middleware\Authorize;
use BeyondCode\LaravelWebSockets\ClientProviders\ConfigClientProvider;
return [
/*
* Path for the Websockets debug console
*/
'path' => '/websockets',
/*
* TODO: add the laravel style comment here
*/
@ -49,6 +45,7 @@ return [
*/
'clients' => [
[
'name' => env('APP_NAME'),
'app_id' => env('WEBSOCKETS_APP_ID'),
'app_key' => env('WEBSOCKETS_APP_KEY'),
'app_secret' => env('WEBSOCKETS_APP_SECRET')
@ -63,4 +60,20 @@ return [
* `ClientProvier` interface.
*/
'client_provider' => ConfigClientProvider::class,
'dashboard' => [
/*
* Path for the Websockets debug console
*/
'path' => '/websockets',
/*
* Middleware that will be applied to the dashboard routes.
*/
'middleware' => [
Authorize::class,
],
]
];

View File

@ -18,12 +18,11 @@
<span class="panel-title">WebSockets Console</span>
<form id="connect" class="form-inline" role="form">
<div class="form-group">
<label class="sr-only" for="appKey">App Key</label>
<input class="form-control" value="{{ env('PUSHER_APP_KEY') }}" id="appKey" placeholder="Enter App Key">
</div>
<div class="form-group">
<label class="sr-only" for="secret">Secret</label>
<input type="password" class="form-control" id="secret" placeholder="Secret">
<select class="form-control" name="app" id="app">
@foreach ($clients as $client)
<option value="{{ $client->appKey }}">{{ $client->name }}</option>
@endforeach
</select>
</div>
<button type="submit" class="btn btn-primary">Connect</button>
</form>
@ -51,9 +50,7 @@
<script>
$(function(){
$('#connect').submit(function(event) {
var appKey = $('#appKey').val();
var secret = $('#secret').val();
connect(appKey, secret);
connect($('#app').val());
event.preventDefault();
});
@ -64,17 +61,16 @@
});
});
function connect(appKey, secret) {
function connect(appKey) {
pusher = new Pusher(appKey, {
wsHost: window.location.hostname,
wsPort: 6001,
wsPath: '/console',
authEndpoint: '{{ config('websockets.path') }}/auth',
authEndpoint: '{{ config('websockets.dashboard.path') }}/auth',
enabledTransports: ['ws', 'flash']
});
var channel = pusher.subscribe('private-logger-new_connection');
channel.bind('private-logger-connection', function(data) {
pusher.subscribe('private-logger-new_connection')
.bind('private-logger-connection', function(data) {
alert(JSON.stringify(data));
});
}

View File

@ -16,6 +16,9 @@ class Client
/** @var string */
public $appSecret;
/** @var string|null */
public $name;
public static function findByAppId(int $appId)
{
return app(ClientProvider::class)->findByAppId($appId);
@ -26,7 +29,7 @@ class Client
return app(ClientProvider::class)->findByAppKey($appKey);
}
public function __construct($appId, string $appKey, string $appSecret)
public function __construct($appId, string $appKey, string $appSecret, ?string $name)
{
if (!is_numeric($appId)) {
throw InvalidClient::appIdIsNotNumeric($appId);
@ -45,6 +48,8 @@ class Client
$this->appKey = $appKey;
$this->appSecret = $appSecret;
$this->name = $name;
}

View File

@ -8,4 +8,6 @@ interface ClientProvider
public function findByAppId(int $appId): ?Client;
public function findByAppKey(string $appKey): ?Client;
public function all(): array;
}

View File

@ -24,6 +24,15 @@ class ConfigClientProvider implements ClientProvider
return $this->instanciate($clientAttributes);
}
public function all(): array
{
return $this->allClients()
->map(function ($client) {
return $this->instanciate($client);
})
->toArray();
}
protected function allClients(): Collection
{
return collect(config('websockets.clients'));
@ -38,7 +47,8 @@ class ConfigClientProvider implements ClientProvider
return new Client(
$clientAttributes['app_id'],
$clientAttributes['app_key'],
$clientAttributes['app_secret']
$clientAttributes['app_secret'],
$clientAttributes['name'] ?? null
);
}
}

View File

@ -2,8 +2,8 @@
namespace BeyondCode\LaravelWebsockets\Http\Controllers;
use Illuminate\Contracts\Broadcasting\Broadcaster;
use Illuminate\Http\Request;
use Illuminate\Contracts\Broadcasting\Broadcaster;
class AuthenticateConsole
{

View File

@ -3,11 +3,14 @@
namespace BeyondCode\LaravelWebsockets\Http\Controllers;
use Illuminate\Http\Request;
use BeyondCode\LaravelWebSockets\ClientProviders\ClientProvider;
class ShowConsole
{
public function __invoke(Request $request)
public function __invoke(Request $request, ClientProvider $clients)
{
return view('websockets::console');
return view('websockets::console', [
'clients' => $clients->all()
]);
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace BeyondCode\LaravelWebsockets\Http\Middleware;
use Illuminate\Support\Facades\Gate;
class Authorize
{
public function handle($request, $next)
{
return Gate::check('viewWebSocketDashboard') ? $next($request) : abort(403);
}
}

View File

@ -1,36 +0,0 @@
<?php
namespace BeyondCode\LaravelWebSockets\LaravelEcho\WebSocket;
use Ratchet\ConnectionInterface;
class ConsoleServer extends PusherServer
{
function onOpen(ConnectionInterface $connection)
{
$this->generateSocketId($connection);
$this->verifyConnection($connection);
$this->establishConnection($connection);
// TODO check connection signature
$connection->isAdmin = true;
}
public function log(string $appId, string $type, string $details)
{
$channelId = "private-logger-{$type}";
$channel = $this->channelManager->find($appId, $channelId);
optional($channel)->broadcast([
'event' => $type,
'channel' => $channelId,
'data' => [
'type' => $type,
'details' => $details
]
]);
}
}

View File

@ -2,9 +2,6 @@
namespace BeyondCode\LaravelWebSockets\LaravelEcho\WebSocket;
use BeyondCode\LaravelWebSockets\ClientProviders\Client;
use BeyondCode\LaravelWebSockets\LaravelEcho\Pusher\Exceptions\PusherException;
use BeyondCode\LaravelWebSockets\LaravelEcho\Pusher\Exceptions\UnknownAppKey;
use Exception;
use Ratchet\ConnectionInterface;
use Ratchet\RFC6455\Messaging\MessageInterface;
@ -19,14 +16,9 @@ class PusherServer extends WebSocketController
/** @var \BeyondCode\LaravelWebSockets\LaravelEcho\Pusher\Channels\ChannelManager */
protected $channelManager;
/** @var ConsoleServer|null */
protected $consoleServer;
public function __construct(ChannelManager $channelManager, ConsoleServer $consoleServer = null)
public function __construct(ChannelManager $channelManager)
{
$this->channelManager = $channelManager;
$this->consoleServer = $consoleServer;
}
function onOpen(ConnectionInterface $connection)
@ -36,8 +28,6 @@ class PusherServer extends WebSocketController
$this->verifyConnection($connection);
$this->establishConnection($connection);
$this->consoleServer->log($connection->appId, 'new_connection', '');
}
public function onMessage(ConnectionInterface $connection, MessageInterface $message)
@ -59,7 +49,6 @@ class PusherServer extends WebSocketController
$exception->getPayload()
));
}
dump($exception);
}
protected function verifyConnection(ConnectionInterface $connection)
@ -94,4 +83,20 @@ class PusherServer extends WebSocketController
$connection->socketId = $socketId;
}
public function log(string $appId, string $type, string $details)
{
$channelId = "private-logger-{$type}";
$channel = $this->channelManager->find($appId, $channelId);
optional($channel)->broadcast([
'event' => $type,
'channel' => $channelId,
'data' => [
'type' => $type,
'details' => $details
]
]);
}
}

View File

@ -2,22 +2,26 @@
namespace BeyondCode\LaravelWebSockets;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Route;
use BeyondCode\LaravelWebSockets\ClientProviders\ClientProvider;
use Illuminate\Support\ServiceProvider;
use BeyondCode\LaravelWebSockets\LaravelEcho\WebSocket\ConsoleServer;
use BeyondCode\LaravelWebSockets\LaravelEcho\Pusher\Channels\ChannelManager;
class LaravelWebSocketsServiceProvider extends ServiceProvider
{
public function boot()
{
Route::middlewareGroup('websockets', config('websockets.dashboard.middleware', []));
$this->publishes([
__DIR__.'/../config/websockets.php' => base_path('config/websockets.php'),
], 'config');
$this->registerRoutes();
$this->registerDashboardGate();
$this->loadViewsFrom(__DIR__.'/../resources/views/', 'websockets');
$this->commands([
@ -36,7 +40,8 @@ class LaravelWebSocketsServiceProvider extends ServiceProvider
{
return [
'namespace' => 'BeyondCode\LaravelWebSockets\Http\Controllers',
'prefix' => config('websockets.path'),
'prefix' => config('websockets.dashboard.path'),
'middleware' => 'websockets'
];
}
@ -55,9 +60,12 @@ class LaravelWebSocketsServiceProvider extends ServiceProvider
$this->app->singleton(ClientProvider::class, function() {
return app(config('websockets.client_provider'));
});
}
$this->app->singleton(ConsoleServer::class, function() {
return new ConsoleServer(new ChannelManager());
protected function registerDashboardGate()
{
Gate::define('viewWebSocketDashboard', function ($user = null) {
return app()->environment('local');
});
}
}

View File

@ -67,8 +67,6 @@ class Router
{
$this->get('/app/{appKey}', LaravelEcho\WebSocket\PusherServer::class);
$this->get('/console/app/{appKey}', LaravelEcho\WebSocket\ConsoleServer::class);
$this->get('/apps/{appId}/channels', LaravelEcho\Http\Controllers\FetchChannels::class);
$this->get('/apps/{appId}/channels/{channelName}', LaravelEcho\Http\Controllers\FetchChannel::class);
$this->get('/apps/{appId}/channels/{channelName}/users', LaravelEcho\Http\Controllers\FetchUsers::class);