From f6c9add25d601da62c6dbe28c8a71d830000b7df Mon Sep 17 00:00:00 2001 From: freek Date: Mon, 3 Dec 2018 23:39:04 +0100 Subject: [PATCH 1/5] wip --- src/Console/StartWebSocketServer.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Console/StartWebSocketServer.php b/src/Console/StartWebSocketServer.php index 6be87ba..2d6363a 100644 --- a/src/Console/StartWebSocketServer.php +++ b/src/Console/StartWebSocketServer.php @@ -53,7 +53,6 @@ class StartWebSocketServer extends Command $browser = new Browser($this->loop, $connector); - app()->singleton(StatisticsLoggerInterface::class, function() use ($browser) { return new HttpStatisticsLogger(app(ChannelManager::class), $browser); }); From 5c93909f31c917be4ccb6efc206ac9ae2113f045 Mon Sep 17 00:00:00 2001 From: freek Date: Mon, 3 Dec 2018 23:45:18 +0100 Subject: [PATCH 2/5] nitpick --- .../Logger/HttpStatisticsLogger.php | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/Statistics/Logger/HttpStatisticsLogger.php b/src/Statistics/Logger/HttpStatisticsLogger.php index 847f319..4b14d42 100644 --- a/src/Statistics/Logger/HttpStatisticsLogger.php +++ b/src/Statistics/Logger/HttpStatisticsLogger.php @@ -11,13 +11,13 @@ use Ratchet\ConnectionInterface; class HttpStatisticsLogger implements StatisticsLogger { - /** @var Statistic[] */ + /** @var \BeyondCode\LaravelWebSockets\Statistics\Statistic[] */ protected $statistics = []; /** @var \BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager */ protected $channelManager; - /** @var Browser */ + /** @var \Clue\React\Buzz\Browser */ protected $browser; public function __construct(ChannelManager $channelManager, Browser $browser) @@ -29,44 +29,46 @@ class HttpStatisticsLogger implements StatisticsLogger public function webSocketMessage(ConnectionInterface $connection) { - $this->initializeStatistics($connection->app->id); - - $this->statistics[$connection->app->id]->webSocketMessage(); + $this + ->findOrMakeStatisticForAppId($connection->app->id) + ->webSocketMessage(); } public function apiMessage($appId) { - $this->initializeStatistics($appId); - - $this->statistics[$appId]->apiMessage(); + $this + ->findOrMakeStatisticForAppId($appId) + ->apiMessage(); } public function connection(ConnectionInterface $connection) { - $this->initializeStatistics($connection->app->id); - - $this->statistics[$connection->app->id]->connection(); + $this + ->findOrMakeStatisticForAppId($connection->app->id) + ->connection(); } public function disconnection(ConnectionInterface $connection) { - $this->initializeStatistics($connection->app->id); - - $this->statistics[$connection->app->id]->disconnection(); + $this + ->findOrMakeStatisticForAppId($connection->app->id) + ->disconnection(); } - protected function initializeStatistics($id) + protected function findOrMakeStatisticForAppId($appId): Statistic { - if (!isset($this->statistics[$id])) { - $this->statistics[$id] = new Statistic($id); + if (! isset($this->statistics[$appId])) { + $this->statistics[$appId] = new Statistic($appId); } + + return $this->statistics[$appId]; } public function save() { foreach ($this->statistics as $appId => $statistic) { - if (!$statistic->isEnabled()) { + if (! $statistic->isEnabled()) { continue; } From 6c96bb8edc9a7eb1bfa8a4224e8b705fa3d987cc Mon Sep 17 00:00:00 2001 From: freek Date: Mon, 3 Dec 2018 23:52:39 +0100 Subject: [PATCH 3/5] wip --- src/Statistics/Logger/HttpStatisticsLogger.php | 14 +++++--------- src/WebSockets/Channels/ChannelManager.php | 6 ++++++ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Statistics/Logger/HttpStatisticsLogger.php b/src/Statistics/Logger/HttpStatisticsLogger.php index 4b14d42..4985ed9 100644 --- a/src/Statistics/Logger/HttpStatisticsLogger.php +++ b/src/Statistics/Logger/HttpStatisticsLogger.php @@ -57,7 +57,7 @@ class HttpStatisticsLogger implements StatisticsLogger protected function findOrMakeStatisticForAppId($appId): Statistic { - if (! isset($this->statistics[$appId])) { + if (!isset($this->statistics[$appId])) { $this->statistics[$appId] = new Statistic($appId); } @@ -68,23 +68,19 @@ class HttpStatisticsLogger implements StatisticsLogger { foreach ($this->statistics as $appId => $statistic) { - if (! $statistic->isEnabled()) { + if (!$statistic->isEnabled()) { continue; } - $this->browser + $this + ->browser ->post( action([WebSocketStatisticsEntriesController::class, 'store']), ['Content-Type' => 'application/json'], stream_for(json_encode($statistic->toArray())) ); - // Reset connection and message count - $currentConnectionCount = collect($this->channelManager->getChannels($appId)) - ->sum(function ($channel) { - return count($channel->getSubscribedConnections()); - }); - + $currentConnectionCount = $this->channelManager->getConnectionCount($appId); $statistic->reset($currentConnectionCount); } } diff --git a/src/WebSockets/Channels/ChannelManager.php b/src/WebSockets/Channels/ChannelManager.php index fa77442..9c7c265 100644 --- a/src/WebSockets/Channels/ChannelManager.php +++ b/src/WebSockets/Channels/ChannelManager.php @@ -46,6 +46,12 @@ class ChannelManager return $this->channels[$appId] ?? []; } + public function getConnectionCount(string $appId): int + { + return collect($this->getChannels($appId)) + ->sum->getSubscribedConnections(); + } + public function removeFromAllChannels(ConnectionInterface $connection) { if (!isset($connection->app)) { From fd2203c8bb0765067511a7a83cf6d5323c006fe8 Mon Sep 17 00:00:00 2001 From: freek Date: Tue, 4 Dec 2018 00:00:35 +0100 Subject: [PATCH 4/5] wip --- config/websockets.php | 17 ++++++++++---- src/Console/StartWebSocketServer.php | 2 +- src/Statistics/Events/StatisticsUpdated.php | 22 +++++++++++-------- .../WebSocketStatisticsEntriesController.php | 2 +- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/config/websockets.php b/config/websockets.php index 693f861..caa8507 100644 --- a/config/websockets.php +++ b/config/websockets.php @@ -42,10 +42,19 @@ return [ */ 'max_request_size_in_kb' => 250, - /* - * This model will be used to store the statistics of the WebSocketsServer - */ - 'statistics_model' => \BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry::class, + 'statistics' => [ + /* + * This model will be used to store the statistics of the WebSocketsServer. + * The only requirement is that the model should be or extend + * `WebSocketsStatisticsEntry` provided by this package. + */ + 'model' => \BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry::class, + + /* + * Here you can specify the interval in seconds at which statistics should be logged. + */ + 'interval_in_seconds' => 60, + ], /* * Define the optional SSL context for your WebSocket connections. diff --git a/src/Console/StartWebSocketServer.php b/src/Console/StartWebSocketServer.php index 2d6363a..2778c5c 100644 --- a/src/Console/StartWebSocketServer.php +++ b/src/Console/StartWebSocketServer.php @@ -57,7 +57,7 @@ class StartWebSocketServer extends Command return new HttpStatisticsLogger(app(ChannelManager::class), $browser); }); - $this->loop->addPeriodicTimer(5, function() { + $this->loop->addPeriodicTimer(config('websockets.statistics.interval_in_seconds'), function() { StatisticsLogger::save(); }); diff --git a/src/Statistics/Events/StatisticsUpdated.php b/src/Statistics/Events/StatisticsUpdated.php index 128a25b..d6fa70b 100644 --- a/src/Statistics/Events/StatisticsUpdated.php +++ b/src/Statistics/Events/StatisticsUpdated.php @@ -3,6 +3,7 @@ namespace BeyondCode\LaravelWebsockets\Statistics\Events; use BeyondCode\LaravelWebSockets\Dashboard\DashboardLogger; +use BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Queue\SerializesModels; @@ -11,27 +12,30 @@ class StatisticsUpdated implements ShouldBroadcast { use SerializesModels; - protected $statisticModel; + /** @var \BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry */ + protected $webSocketsStatisticsEntry; - public function __construct($statisticModel) + public function __construct(WebSocketsStatisticsEntry $webSocketsStatisticsEntry) { - $this->statisticModel = $statisticModel; + $this->webSocketsStatisticsEntry = $webSocketsStatisticsEntry; } public function broadcastWith() { return [ - 'time' => $this->statisticModel->created_at->timestamp, - 'app_id' => $this->statisticModel->appId, - 'peak_connection_count' => $this->statisticModel->peakConnectionCount, - 'websocket_message_count' => $this->statisticModel->webSocketMessageCount, - 'api_message_count' => $this->statisticModel->apiMessageCount, + 'time' => $this->webSocketsStatisticsEntry->created_at->timestamp, + 'app_id' => $this->webSocketsStatisticsEntry->appId, + 'peak_connection_count' => $this->webSocketsStatisticsEntry->peakConnectionCount, + 'websocket_message_count' => $this->webSocketsStatisticsEntry->webSocketMessageCount, + 'api_message_count' => $this->webSocketsStatisticsEntry->apiMessageCount, ]; } public function broadcastOn() { - return new PrivateChannel(str_after(DashboardLogger::LOG_CHANNEL_PREFIX . 'statistics', 'private-')); + $channelName = str_after(DashboardLogger::LOG_CHANNEL_PREFIX . 'statistics', 'private-'); + + return new PrivateChannel($channelName); } public function broadcastAs() diff --git a/src/Statistics/Http/Controllers/WebSocketStatisticsEntriesController.php b/src/Statistics/Http/Controllers/WebSocketStatisticsEntriesController.php index 2279a0e..f898b2e 100644 --- a/src/Statistics/Http/Controllers/WebSocketStatisticsEntriesController.php +++ b/src/Statistics/Http/Controllers/WebSocketStatisticsEntriesController.php @@ -17,7 +17,7 @@ class WebSocketStatisticsEntriesController 'api_message_count' => 'required|integer', ]); - $webSocketsStatisticsEntryModelClass = config('websockets.statistics_model'); + $webSocketsStatisticsEntryModelClass = config('websockets.statistics.model'); $statisticModel = $webSocketsStatisticsEntryModelClass::create($validatedAttributes); From e738d30c1a5a242d2145046f5594bbf7644d5c27 Mon Sep 17 00:00:00 2001 From: freek Date: Tue, 4 Dec 2018 00:05:05 +0100 Subject: [PATCH 5/5] wip --- src/WebSocketsServiceProvider.php | 41 +++++++++++++++++-------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/WebSocketsServiceProvider.php b/src/WebSocketsServiceProvider.php index 0c6901b..36afd03 100644 --- a/src/WebSocketsServiceProvider.php +++ b/src/WebSocketsServiceProvider.php @@ -22,22 +22,21 @@ class WebSocketsServiceProvider extends ServiceProvider public function boot() { $this->publishes([ - __DIR__.'/../config/websockets.php' => base_path('config/websockets.php'), + __DIR__ . '/../config/websockets.php' => base_path('config/websockets.php'), ], 'config'); - if (! class_exists('CreateWebSocketsStatisticsEntries')) { + if (!class_exists('CreateWebSocketsStatisticsEntries')) { $this->publishes([ - __DIR__.'/../database/migrations/create_websockets_statistics_entries_table.php.stub' => database_path('migrations/'.date('Y_m_d_His', time()).'_create_websockets_statistics_entries_table.php'), + __DIR__ . '/../database/migrations/create_websockets_statistics_entries_table.php.stub' => database_path('migrations/' . date('Y_m_d_His', time()) . '_create_websockets_statistics_entries_table.php'), ], 'migrations'); } - $this->registerRouteMacro(); + $this + ->registerRouteMacro() + ->registerStatisticRoute() + ->registerDashboardGate(); - $this->registerStatisticRoute(); - - $this->registerDashboardGate(); - - $this->loadViewsFrom(__DIR__.'/../resources/views/', 'websockets'); + $this->loadViewsFrom(__DIR__ . '/../resources/views/', 'websockets'); $this->commands([ Console\StartWebSocketServer::class, @@ -46,38 +45,42 @@ class WebSocketsServiceProvider extends ServiceProvider public function register() { - $this->mergeConfigFrom(__DIR__.'/../config/websockets.php', 'websockets'); + $this->mergeConfigFrom(__DIR__ . '/../config/websockets.php', 'websockets'); - $this->app->singleton('websockets.router', function() { + $this->app->singleton('websockets.router', function () { return new Router(); }); - $this->app->singleton(ChannelManager::class, function() { + $this->app->singleton(ChannelManager::class, function () { return new ChannelManager(); }); - $this->app->singleton(AppProvider::class, function() { + $this->app->singleton(AppProvider::class, function () { return app(config('websockets.app_provider')); }); } protected function registerRouteMacro() { - Route::macro('webSockets', function($prefix = 'laravel-websockets') { - Route::prefix($prefix)->namespace('\\')->middleware(Authorize::class)->group(function() { - Route::get('/', ShowDashboard::class); - Route::get('/api/{appId}/statistics', DashboardApiController::class.'@getStatistics'); + Route::macro('webSockets', function ($prefix = 'laravel-websockets') { + Route::prefix($prefix)->namespace('\\')->middleware(Authorize::class)->group(function () { + Route::get('/', ShowDashboard::class); + Route::get('/api/{appId}/statistics', DashboardApiController::class . '@getStatistics'); Route::post('auth', AuthenticateDashboard::class); Route::post('event', SendMessage::class); }); }); + + return $this; } protected function registerStatisticRoute() { - Route::prefix('/laravel-websockets')->namespace('\\')->group(function() { + Route::prefix('/laravel-websockets')->namespace('\\')->group(function () { Route::post('statistics', [WebSocketStatisticsEntriesController::class, 'store']); }); + + return $this; } protected function registerDashboardGate() @@ -85,5 +88,7 @@ class WebSocketsServiceProvider extends ServiceProvider Gate::define('viewWebSocketsDashboard', function ($user = null) { return app()->environment('local'); }); + + return $this; } }