diff --git a/resources/views/dashboard.blade.php b/resources/views/dashboard.blade.php index 9b7a200..1121fad 100644 --- a/resources/views/dashboard.blade.php +++ b/resources/views/dashboard.blade.php @@ -84,9 +84,29 @@ v-if="connected && app.statisticsEnabled" class="w-full my-6 px-6" > -
- Live statistics -
+
+ + Live statistics + + +
+
+ + Refresh automatically +
+ + +
+
{ if (event.error.data.code === 4100) { this.connected = false; this.logs = []; + this.chart = null; throw new Error("Over capacity"); } @@ -288,12 +326,12 @@ }); this.subscribeToAllChannels(); - this.subscribeToStatistics(); }, disconnect () { this.pusher.disconnect(); this.connecting = false; + this.chart = null; }, loadChart () { @@ -333,7 +371,10 @@ autosize: true, }; - this.chart = Plotly.newPlot('statisticsChart', chartData, layout); + this.chart = this.chart + ? Plotly.react('statisticsChart', chartData, layout) + : Plotly.newPlot('statisticsChart', chartData, layout); + }); }, @@ -348,18 +389,6 @@ }); }, - subscribeToStatistics () { - this.pusher.subscribe('{{ $logPrefix }}statistics') - .bind('statistics-updated', (data) => { - var update = { - x: [[data.time], [data.time], [data.time]], - y: [[data.peak_connection_count], [data.websocket_message_count], [data.api_message_count]], - }; - - Plotly.extendTraces('statisticsChart', update, [0, 1, 2]); - }); - }, - sendEvent () { if (! this.sendingEvent) { this.sendingEvent = true; @@ -415,6 +444,17 @@ return 'bg-gray-700 text-white'; }, + + startRefreshInterval () { + this.refreshTicker = setInterval(function () { + this.loadChart(); + }.bind(this), this.refreshInterval * 1000); + }, + + stopRefreshInterval () { + clearInterval(this.refreshTicker); + this.refreshTicker = null; + }, }, }); diff --git a/src/Dashboard/Http/Controllers/DashboardApiController.php b/src/Dashboard/Http/Controllers/DashboardApiController.php index 1e63fb9..c240905 100644 --- a/src/Dashboard/Http/Controllers/DashboardApiController.php +++ b/src/Dashboard/Http/Controllers/DashboardApiController.php @@ -2,45 +2,21 @@ namespace BeyondCode\LaravelWebSockets\Dashboard\Http\Controllers; +use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver; +use Illuminate\Http\Request; + class DashboardApiController { /** * Get statistics for an app ID. * + * @param \Illuminate\Http\Request $request + * @param \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver $driver * @param mixed $appId * @return \Illuminate\Http\Response */ - public function getStatistics($appId) + public function getStatistics(Request $request, StatisticsDriver $driver, $appId) { - $model = config('websockets.statistics.model'); - - $statistics = $model::where('app_id', $appId) - ->latest() - ->limit(120) - ->get(); - - $statisticData = $statistics->map(function ($statistic) { - return [ - 'timestamp' => (string) $statistic->created_at, - 'peak_connection_count' => $statistic->peak_connection_count, - 'websocket_message_count' => $statistic->websocket_message_count, - 'api_message_count' => $statistic->api_message_count, - ]; - })->reverse(); - - return [ - 'peak_connections' => [ - 'x' => $statisticData->pluck('timestamp'), - 'y' => $statisticData->pluck('peak_connection_count'), - ], - 'websocket_message_count' => [ - 'x' => $statisticData->pluck('timestamp'), - 'y' => $statisticData->pluck('websocket_message_count'), - ], - 'api_message_count' => [ - 'x' => $statisticData->pluck('timestamp'), - 'y' => $statisticData->pluck('api_message_count'), - ], - ]; + return $driver::get($appId, $request); } } diff --git a/src/Dashboard/Http/Controllers/ShowDashboard.php b/src/Dashboard/Http/Controllers/ShowDashboard.php index 8ce4208..f6dc6b1 100644 --- a/src/Dashboard/Http/Controllers/ShowDashboard.php +++ b/src/Dashboard/Http/Controllers/ShowDashboard.php @@ -22,6 +22,7 @@ class ShowDashboard 'port' => config('websockets.dashboard.port', 6001), 'channels' => DashboardLogger::$channels, 'logPrefix' => DashboardLogger::LOG_CHANNEL_PREFIX, + 'refreshInterval' => config('websockets.statistics.interval_in_seconds'), ]); } } diff --git a/src/Statistics/Drivers/DatabaseDriver.php b/src/Statistics/Drivers/DatabaseDriver.php index a8d5175..cb5e353 100644 --- a/src/Statistics/Drivers/DatabaseDriver.php +++ b/src/Statistics/Drivers/DatabaseDriver.php @@ -3,6 +3,7 @@ namespace BeyondCode\LaravelWebSockets\Statistics\Drivers; use Carbon\Carbon; +use Illuminate\Http\Request; class DatabaseDriver implements StatisticsDriver { @@ -87,6 +88,46 @@ class DatabaseDriver implements StatisticsDriver return new static($class::create($data)); } + /** + * Get the records to show to the dashboard. + * + * @param mixed $appId + * @param \Illuminate\Http\Request $request + * @return array + */ + public static function get($appId, Request $request): array + { + $class = config('websockets.statistics.database.model'); + + $statistics = $class::whereAppId($appId) + ->latest() + ->limit(120) + ->get() + ->map(function ($statistic) { + return [ + 'timestamp' => (string) $statistic->created_at, + 'peak_connection_count' => $statistic->peak_connection_count, + 'websocket_message_count' => $statistic->websocket_message_count, + 'api_message_count' => $statistic->api_message_count, + ]; + })->reverse(); + + return [ + 'peak_connections' => [ + 'x' => $statistics->pluck('timestamp'), + 'y' => $statistics->pluck('peak_connection_count'), + ], + 'websocket_message_count' => [ + 'x' => $statistics->pluck('timestamp'), + 'y' => $statistics->pluck('websocket_message_count'), + ], + 'api_message_count' => [ + 'x' => $statistics->pluck('timestamp'), + 'y' => $statistics->pluck('api_message_count'), + ], + ]; + } + /** * Delete statistics from the store, * optionally by app id, returning diff --git a/src/Statistics/Drivers/StatisticsDriver.php b/src/Statistics/Drivers/StatisticsDriver.php index 8ed1e5e..9b9cfb0 100644 --- a/src/Statistics/Drivers/StatisticsDriver.php +++ b/src/Statistics/Drivers/StatisticsDriver.php @@ -2,6 +2,8 @@ namespace BeyondCode\LaravelWebSockets\Statistics\Drivers; +use Illuminate\Http\Request; + interface StatisticsDriver { /** @@ -55,6 +57,15 @@ interface StatisticsDriver */ public static function create(array $data): StatisticsDriver; + /** + * Get the records to show to the dashboard. + * + * @param mixed $appId + * @param \Illuminate\Http\Request $request + * @return void + */ + public static function get($appId, Request $request); + /** * Delete statistics from the store, * optionally by app id, returning diff --git a/src/Statistics/Events/StatisticsUpdated.php b/src/Statistics/Events/StatisticsUpdated.php deleted file mode 100644 index b3c76b4..0000000 --- a/src/Statistics/Events/StatisticsUpdated.php +++ /dev/null @@ -1,73 +0,0 @@ -driver = $driver; - } - - /** - * Format the broadcasting message. - * - * @return array - */ - public function broadcastWith() - { - return [ - 'time' => $this->driver->getTime(), - 'app_id' => $this->driver->getAppId(), - 'peak_connection_count' => $this->driver->getPeakConnectionCount(), - 'websocket_message_count' => $this->driver->getWebsocketMessageCount(), - 'api_message_count' => $this->driver->getApiMessageCount(), - ]; - } - - /** - * Specify the channel to broadcast on. - * - * @return \Illuminate\Broadcasting\Channel - */ - public function broadcastOn() - { - $channelName = Str::after(DashboardLogger::LOG_CHANNEL_PREFIX.'statistics', 'private-'); - - return new PrivateChannel( - Str::after(DashboardLogger::LOG_CHANNEL_PREFIX.'statistics', 'private-') - ); - } - - /** - * Define the broadcasted event name. - * - * @return string - */ - public function broadcastAs() - { - return 'statistics-updated'; - } -} diff --git a/src/Statistics/Logger/MemoryStatisticsLogger.php b/src/Statistics/Logger/MemoryStatisticsLogger.php index 39d4a69..fe0ac82 100644 --- a/src/Statistics/Logger/MemoryStatisticsLogger.php +++ b/src/Statistics/Logger/MemoryStatisticsLogger.php @@ -4,7 +4,6 @@ namespace BeyondCode\LaravelWebSockets\Statistics\Logger; use BeyondCode\LaravelWebSockets\Apps\App; use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver; -use BeyondCode\LaravelWebSockets\Statistics\Events\StatisticsUpdated; use BeyondCode\LaravelWebSockets\Statistics\Statistic; use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager; use Ratchet\ConnectionInterface; @@ -105,9 +104,7 @@ class MemoryStatisticsLogger implements StatisticsLogger continue; } - /* broadcast(new StatisticsUpdated( - $this->driver::create($statistic->toArray()) - )); */ + $this->driver::create($statistic->toArray()); $currentConnectionCount = $this->channelManager->getConnectionCount($appId);