diff --git a/config/websockets.php b/config/websockets.php
index bddb3d5633..a2e29b2808 100644
--- a/config/websockets.php
+++ b/config/websockets.php
@@ -239,37 +239,6 @@
'delete_statistics_older_than_days' => 60,
- /*
- |--------------------------------------------------------------------------
- | DNS Lookup
- |--------------------------------------------------------------------------
- |
- | Use an DNS resolver to make the requests to the statistics logger
- | default is to resolve everything to 127.0.0.1.
- |
- */
-
- 'perform_dns_lookup' => false,
-
- /*
- |--------------------------------------------------------------------------
- | DNS Lookup TLS Settings
- |--------------------------------------------------------------------------
- |
- | You can configure the DNS Lookup Connector the TLS settings.
- | Check the available options here:
- | https://github.com/reactphp/socket/blob/master/src/Connector.php#L29
- |
- */
-
- 'tls' => [
-
- 'verify_peer' => env('APP_ENV') === 'production',
-
- 'verify_peer_name' => env('APP_ENV') === 'production',
-
- ],
-
],
];
diff --git a/resources/views/dashboard.blade.php b/resources/views/dashboard.blade.php
index 9b7a20091a..1121fadb6f 100644
--- a/resources/views/dashboard.blade.php
+++ b/resources/views/dashboard.blade.php
@@ -84,9 +84,29 @@ class="rounded-full px-3 py-2 text-white focus:outline-none"
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 @@ class="rounded-full px-3 py-1 inline-block text-sm"
});
this.subscribeToAllChannels();
- this.subscribeToStatistics();
},
disconnect () {
this.pusher.disconnect();
this.connecting = false;
+ this.chart = null;
},
loadChart () {
@@ -333,7 +371,10 @@ class="rounded-full px-3 py-1 inline-block text-sm"
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 @@ class="rounded-full px-3 py-1 inline-block text-sm"
});
},
- 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 @@ class="rounded-full px-3 py-1 inline-block text-sm"
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/Console/StartWebSocketServer.php b/src/Console/StartWebSocketServer.php
index 70932ba798..d6c4dcb4ed 100644
--- a/src/Console/StartWebSocketServer.php
+++ b/src/Console/StartWebSocketServer.php
@@ -11,17 +11,12 @@
use BeyondCode\LaravelWebSockets\Server\Logger\HttpLogger;
use BeyondCode\LaravelWebSockets\Server\Logger\WebsocketsLogger;
use BeyondCode\LaravelWebSockets\Server\WebSocketServerFactory;
-use BeyondCode\LaravelWebSockets\Statistics\DnsResolver;
+use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
use BeyondCode\LaravelWebSockets\Statistics\Logger\StatisticsLogger as StatisticsLoggerInterface;
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
-use Clue\React\Buzz\Browser;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Cache;
-use React\Dns\Config\Config as DnsConfig;
-use React\Dns\Resolver\Factory as DnsFactory;
-use React\Dns\Resolver\ResolverInterface;
use React\EventLoop\Factory as LoopFactory;
-use React\Socket\Connector;
class StartWebSocketServer extends Command
{
@@ -103,19 +98,12 @@ public function handle()
*/
protected function configureStatisticsLogger()
{
- $connector = new Connector($this->loop, [
- 'dns' => $this->getDnsResolver(),
- 'tls' => config('websockets.statistics.tls'),
- ]);
-
- $browser = new Browser($this->loop, $connector);
-
- $this->laravel->singleton(StatisticsLoggerInterface::class, function () use ($browser) {
+ $this->laravel->singleton(StatisticsLoggerInterface::class, function () {
$class = config('websockets.statistics.logger', \BeyondCode\LaravelWebSockets\Statistics\Logger\MemoryStatisticsLogger::class);
return new $class(
$this->laravel->make(ChannelManager::class),
- $browser
+ $this->laravel->make(StatisticsDriver::class)
);
});
@@ -273,27 +261,6 @@ protected function buildServer()
->createServer();
}
- /**
- * Create a DNS resolver for the stats manager.
- *
- * @return \React\Dns\Resolver\ResolverInterface
- */
- protected function getDnsResolver(): ResolverInterface
- {
- if (! config('websockets.statistics.perform_dns_lookup')) {
- return new DnsResolver;
- }
-
- $dnsConfig = DnsConfig::loadSystemConfigBlocking();
-
- return (new DnsFactory)->createCached(
- $dnsConfig->nameservers
- ? reset($dnsConfig->nameservers)
- : '1.1.1.1',
- $this->loop
- );
- }
-
/**
* Get the last time the server restarted.
*
diff --git a/src/Dashboard/Http/Controllers/DashboardApiController.php b/src/Dashboard/Http/Controllers/DashboardApiController.php
index 1e63fb9417..c240905b2d 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 8ce4208e8d..f6dc6b13ac 100644
--- a/src/Dashboard/Http/Controllers/ShowDashboard.php
+++ b/src/Dashboard/Http/Controllers/ShowDashboard.php
@@ -22,6 +22,7 @@ public function __invoke(Request $request, AppManager $apps)
'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 a8d5175a85..cb5e353743 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 @@ public static function create(array $data): 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 8ed1e5ec02..9b9cfb0452 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 @@ public function getApiMessageCount(): int;
*/
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 b3c76b49f1..0000000000
--- 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/Http/Controllers/WebSocketStatisticsEntriesController.php b/src/Statistics/Http/Controllers/WebSocketStatisticsEntriesController.php
deleted file mode 100644
index bf9453bbe3..0000000000
--- a/src/Statistics/Http/Controllers/WebSocketStatisticsEntriesController.php
+++ /dev/null
@@ -1,34 +0,0 @@
-validate([
- 'app_id' => ['required', new AppId()],
- 'peak_connection_count' => 'required|integer',
- 'websocket_message_count' => 'required|integer',
- 'api_message_count' => 'required|integer',
- ]);
-
- broadcast(new StatisticsUpdated(
- $driver::create($validatedAttributes)
- ));
-
- return 'ok';
- }
-}
diff --git a/src/Statistics/Http/Middleware/Authorize.php b/src/Statistics/Http/Middleware/Authorize.php
deleted file mode 100644
index cadd0d6958..0000000000
--- a/src/Statistics/Http/Middleware/Authorize.php
+++ /dev/null
@@ -1,22 +0,0 @@
-secret))
- ? abort(403)
- : $next($request);
- }
-}
diff --git a/src/Statistics/Logger/MemoryStatisticsLogger.php b/src/Statistics/Logger/MemoryStatisticsLogger.php
index 224ddfec03..fe0ac82e5d 100644
--- a/src/Statistics/Logger/MemoryStatisticsLogger.php
+++ b/src/Statistics/Logger/MemoryStatisticsLogger.php
@@ -3,11 +3,9 @@
namespace BeyondCode\LaravelWebSockets\Statistics\Logger;
use BeyondCode\LaravelWebSockets\Apps\App;
-use BeyondCode\LaravelWebSockets\Statistics\Http\Controllers\WebSocketStatisticsEntriesController;
+use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
use BeyondCode\LaravelWebSockets\Statistics\Statistic;
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
-use Clue\React\Buzz\Browser;
-use function GuzzleHttp\Psr7\stream_for;
use Ratchet\ConnectionInterface;
class MemoryStatisticsLogger implements StatisticsLogger
@@ -27,23 +25,23 @@ class MemoryStatisticsLogger implements StatisticsLogger
protected $channelManager;
/**
- * The Browser instance.
+ * The statistics driver instance.
*
- * @var \Clue\React\Buzz\Browser
+ * @var \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver
*/
- protected $browser;
+ protected $driver;
/**
* Initialize the logger.
*
* @param \BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager $channelManager
- * @param \Clue\React\Buzz\Browser $browser
+ * @param \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver $driver
* @return void
*/
- public function __construct(ChannelManager $channelManager, Browser $browser)
+ public function __construct(ChannelManager $channelManager, StatisticsDriver $driver)
{
$this->channelManager = $channelManager;
- $this->browser = $browser;
+ $this->driver = $driver;
}
/**
@@ -106,16 +104,7 @@ public function save()
continue;
}
- $postData = array_merge($statistic->toArray(), [
- 'secret' => App::findById($appId)->secret,
- ]);
-
- $this->browser
- ->post(
- action([WebSocketStatisticsEntriesController::class, 'store']),
- ['Content-Type' => 'application/json'],
- stream_for(json_encode($postData))
- );
+ $this->driver::create($statistic->toArray());
$currentConnectionCount = $this->channelManager->getConnectionCount($appId);
diff --git a/src/Statistics/Logger/NullStatisticsLogger.php b/src/Statistics/Logger/NullStatisticsLogger.php
index ee8728ef98..94e35475af 100644
--- a/src/Statistics/Logger/NullStatisticsLogger.php
+++ b/src/Statistics/Logger/NullStatisticsLogger.php
@@ -2,8 +2,8 @@
namespace BeyondCode\LaravelWebSockets\Statistics\Logger;
+use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
-use Clue\React\Buzz\Browser;
use Ratchet\ConnectionInterface;
class NullStatisticsLogger implements StatisticsLogger
@@ -16,23 +16,23 @@ class NullStatisticsLogger implements StatisticsLogger
protected $channelManager;
/**
- * The Browser instance.
+ * The statistics driver instance.
*
- * @var \Clue\React\Buzz\Browser
+ * @var \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver
*/
- protected $browser;
+ protected $driver;
/**
* Initialize the logger.
*
* @param \BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager $channelManager
- * @param \Clue\React\Buzz\Browser $browser
+ * @param \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver $driver
* @return void
*/
- public function __construct(ChannelManager $channelManager, Browser $browser)
+ public function __construct(ChannelManager $channelManager, StatisticsDriver $driver)
{
$this->channelManager = $channelManager;
- $this->browser = $browser;
+ $this->driver = $driver;
}
/**
diff --git a/src/WebSocketsServiceProvider.php b/src/WebSocketsServiceProvider.php
index 297820fab0..09db7784ac 100644
--- a/src/WebSocketsServiceProvider.php
+++ b/src/WebSocketsServiceProvider.php
@@ -11,8 +11,6 @@
use BeyondCode\LaravelWebSockets\PubSub\Broadcasters\RedisPusherBroadcaster;
use BeyondCode\LaravelWebSockets\Server\Router;
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
-use BeyondCode\LaravelWebSockets\Statistics\Http\Controllers\WebSocketStatisticsEntriesController;
-use BeyondCode\LaravelWebSockets\Statistics\Http\Middleware\Authorize as AuthorizeStatistics;
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManagers\ArrayChannelManager;
use Illuminate\Broadcasting\BroadcastManager;
@@ -127,10 +125,6 @@ protected function registerDashboardRoutes()
Route::post('auth', AuthenticateDashboard::class);
Route::post('event', SendMessage::class);
});
-
- Route::middleware(AuthorizeStatistics::class)->group(function () {
- Route::post('statistics', [WebSocketStatisticsEntriesController::class, 'store']);
- });
});
return $this;
diff --git a/tests/Statistics/Controllers/WebSocketsStatisticsControllerTest.php b/tests/Statistics/Controllers/WebSocketsStatisticsControllerTest.php
deleted file mode 100644
index 360518f67a..0000000000
--- a/tests/Statistics/Controllers/WebSocketsStatisticsControllerTest.php
+++ /dev/null
@@ -1,42 +0,0 @@
-post(
- action([WebSocketStatisticsEntriesController::class, 'store']),
- array_merge($this->payload(), [
- 'secret' => config('websockets.apps.0.secret'),
- ])
- );
-
- $entries = WebSocketsStatisticsEntry::get();
-
- $this->assertCount(1, $entries);
-
- $actual = $entries->first()->attributesToArray();
-
- foreach ($this->payload() as $key => $value) {
- $this->assertArrayHasKey($key, $actual);
- $this->assertSame($value, $actual[$key]);
- }
- }
-
- protected function payload(): array
- {
- return [
- 'app_id' => config('websockets.apps.0.id'),
- 'peak_connection_count' => '1',
- 'websocket_message_count' => '2',
- 'api_message_count' => '3',
- ];
- }
-}
diff --git a/tests/TestCase.php b/tests/TestCase.php
index 664bf28254..b0c7b7affa 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -6,13 +6,12 @@
use BeyondCode\LaravelWebSockets\PubSub\Drivers\LocalClient;
use BeyondCode\LaravelWebSockets\PubSub\Drivers\RedisClient;
use BeyondCode\LaravelWebSockets\PubSub\ReplicationInterface;
+use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
use BeyondCode\LaravelWebSockets\Tests\Mocks\Connection;
use BeyondCode\LaravelWebSockets\Tests\Mocks\Message;
use BeyondCode\LaravelWebSockets\Tests\Statistics\Logger\FakeStatisticsLogger;
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
-use Clue\React\Buzz\Browser;
use GuzzleHttp\Psr7\Request;
-use Mockery;
use Ratchet\ConnectionInterface;
use React\EventLoop\Factory as LoopFactory;
@@ -45,7 +44,7 @@ public function setUp(): void
StatisticsLogger::swap(new FakeStatisticsLogger(
$this->channelManager,
- Mockery::mock(Browser::class)
+ app(StatisticsDriver::class)
));
$this->loadMigrationsFrom(__DIR__.'/../database/migrations');
@@ -94,8 +93,6 @@ protected function getEnvironmentSetUp($app)
],
]);
- $app['config']->set('websockets.statistics.perform_dns_lookup', true);
-
$app['config']->set('database.redis.default', [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),