Replacing event with continously statistics polling
This commit is contained in:
parent
f9cf723c0e
commit
70ce44e635
|
|
@ -84,9 +84,29 @@
|
||||||
v-if="connected && app.statisticsEnabled"
|
v-if="connected && app.statisticsEnabled"
|
||||||
class="w-full my-6 px-6"
|
class="w-full my-6 px-6"
|
||||||
>
|
>
|
||||||
<div class="font-semibold uppercase text-gray-700">
|
<div class="flex justify-between items-center">
|
||||||
Live statistics
|
<span class="font-semibold uppercase text-gray-700">
|
||||||
</div>
|
Live statistics
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div class="space-x-3 flex items-center">
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
v-model="autoRefresh"
|
||||||
|
class="mr-2"
|
||||||
|
/>
|
||||||
|
Refresh automatically
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
@click="loadChart"
|
||||||
|
class="rounded-full bg-blue-500 hover:bg-blue-600 focus:outline-none text-white px-3 py-1"
|
||||||
|
>
|
||||||
|
Refresh
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
id="statisticsChart"
|
id="statisticsChart"
|
||||||
|
|
@ -222,6 +242,9 @@
|
||||||
connected: false,
|
connected: false,
|
||||||
connecting: false,
|
connecting: false,
|
||||||
sendingEvent: false,
|
sendingEvent: false,
|
||||||
|
autoRefresh: true,
|
||||||
|
refreshInterval: {{ $refreshInterval }},
|
||||||
|
refreshTicker: null,
|
||||||
chart: null,
|
chart: null,
|
||||||
pusher: null,
|
pusher: null,
|
||||||
app: null,
|
app: null,
|
||||||
|
|
@ -236,6 +259,19 @@
|
||||||
mounted () {
|
mounted () {
|
||||||
this.app = this.apps[0] || null;
|
this.app = this.apps[0] || null;
|
||||||
},
|
},
|
||||||
|
destroyed () {
|
||||||
|
if (this.refreshTicker) {
|
||||||
|
this.clearRefreshInterval();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
connected (newVal) {
|
||||||
|
newVal ? this.startRefreshInterval() : this.clearRefreshInterval();
|
||||||
|
},
|
||||||
|
autoRefresh (newVal) {
|
||||||
|
newVal ? this.startRefreshInterval() : this.clearRefreshInterval();
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
connect () {
|
connect () {
|
||||||
this.connecting = true;
|
this.connecting = true;
|
||||||
|
|
@ -274,12 +310,14 @@
|
||||||
this.connected = false;
|
this.connected = false;
|
||||||
this.connecting = false;
|
this.connecting = false;
|
||||||
this.logs = [];
|
this.logs = [];
|
||||||
|
this.chart = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.pusher.connection.bind('error', event => {
|
this.pusher.connection.bind('error', event => {
|
||||||
if (event.error.data.code === 4100) {
|
if (event.error.data.code === 4100) {
|
||||||
this.connected = false;
|
this.connected = false;
|
||||||
this.logs = [];
|
this.logs = [];
|
||||||
|
this.chart = null;
|
||||||
|
|
||||||
throw new Error("Over capacity");
|
throw new Error("Over capacity");
|
||||||
}
|
}
|
||||||
|
|
@ -288,12 +326,12 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
this.subscribeToAllChannels();
|
this.subscribeToAllChannels();
|
||||||
this.subscribeToStatistics();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
disconnect () {
|
disconnect () {
|
||||||
this.pusher.disconnect();
|
this.pusher.disconnect();
|
||||||
this.connecting = false;
|
this.connecting = false;
|
||||||
|
this.chart = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
loadChart () {
|
loadChart () {
|
||||||
|
|
@ -333,7 +371,10 @@
|
||||||
autosize: true,
|
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 () {
|
sendEvent () {
|
||||||
if (! this.sendingEvent) {
|
if (! this.sendingEvent) {
|
||||||
this.sendingEvent = true;
|
this.sendingEvent = true;
|
||||||
|
|
@ -415,6 +444,17 @@
|
||||||
|
|
||||||
return 'bg-gray-700 text-white';
|
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;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -2,45 +2,21 @@
|
||||||
|
|
||||||
namespace BeyondCode\LaravelWebSockets\Dashboard\Http\Controllers;
|
namespace BeyondCode\LaravelWebSockets\Dashboard\Http\Controllers;
|
||||||
|
|
||||||
|
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class DashboardApiController
|
class DashboardApiController
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Get statistics for an app ID.
|
* Get statistics for an app ID.
|
||||||
*
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver $driver
|
||||||
* @param mixed $appId
|
* @param mixed $appId
|
||||||
* @return \Illuminate\Http\Response
|
* @return \Illuminate\Http\Response
|
||||||
*/
|
*/
|
||||||
public function getStatistics($appId)
|
public function getStatistics(Request $request, StatisticsDriver $driver, $appId)
|
||||||
{
|
{
|
||||||
$model = config('websockets.statistics.model');
|
return $driver::get($appId, $request);
|
||||||
|
|
||||||
$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'),
|
|
||||||
],
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ class ShowDashboard
|
||||||
'port' => config('websockets.dashboard.port', 6001),
|
'port' => config('websockets.dashboard.port', 6001),
|
||||||
'channels' => DashboardLogger::$channels,
|
'channels' => DashboardLogger::$channels,
|
||||||
'logPrefix' => DashboardLogger::LOG_CHANNEL_PREFIX,
|
'logPrefix' => DashboardLogger::LOG_CHANNEL_PREFIX,
|
||||||
|
'refreshInterval' => config('websockets.statistics.interval_in_seconds'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
namespace BeyondCode\LaravelWebSockets\Statistics\Drivers;
|
namespace BeyondCode\LaravelWebSockets\Statistics\Drivers;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class DatabaseDriver implements StatisticsDriver
|
class DatabaseDriver implements StatisticsDriver
|
||||||
{
|
{
|
||||||
|
|
@ -87,6 +88,46 @@ class DatabaseDriver implements StatisticsDriver
|
||||||
return new static($class::create($data));
|
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,
|
* Delete statistics from the store,
|
||||||
* optionally by app id, returning
|
* optionally by app id, returning
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace BeyondCode\LaravelWebSockets\Statistics\Drivers;
|
namespace BeyondCode\LaravelWebSockets\Statistics\Drivers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
interface StatisticsDriver
|
interface StatisticsDriver
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
@ -55,6 +57,15 @@ interface StatisticsDriver
|
||||||
*/
|
*/
|
||||||
public static function create(array $data): 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,
|
* Delete statistics from the store,
|
||||||
* optionally by app id, returning
|
* optionally by app id, returning
|
||||||
|
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace BeyondCode\LaravelWebSockets\Statistics\Events;
|
|
||||||
|
|
||||||
use BeyondCode\LaravelWebSockets\Dashboard\DashboardLogger;
|
|
||||||
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
|
|
||||||
use Illuminate\Broadcasting\PrivateChannel;
|
|
||||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
|
||||||
use Illuminate\Queue\SerializesModels;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
|
|
||||||
class StatisticsUpdated implements ShouldBroadcast
|
|
||||||
{
|
|
||||||
use SerializesModels;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The statistics driver instance.
|
|
||||||
*
|
|
||||||
* @var \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver
|
|
||||||
*/
|
|
||||||
protected $driver;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the event.
|
|
||||||
*
|
|
||||||
* @param \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver $driver
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function __construct(StatisticsDriver $driver)
|
|
||||||
{
|
|
||||||
$this->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';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -4,7 +4,6 @@ namespace BeyondCode\LaravelWebSockets\Statistics\Logger;
|
||||||
|
|
||||||
use BeyondCode\LaravelWebSockets\Apps\App;
|
use BeyondCode\LaravelWebSockets\Apps\App;
|
||||||
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
|
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
|
||||||
use BeyondCode\LaravelWebSockets\Statistics\Events\StatisticsUpdated;
|
|
||||||
use BeyondCode\LaravelWebSockets\Statistics\Statistic;
|
use BeyondCode\LaravelWebSockets\Statistics\Statistic;
|
||||||
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
|
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
|
||||||
use Ratchet\ConnectionInterface;
|
use Ratchet\ConnectionInterface;
|
||||||
|
|
@ -105,9 +104,7 @@ class MemoryStatisticsLogger implements StatisticsLogger
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* broadcast(new StatisticsUpdated(
|
$this->driver::create($statistic->toArray());
|
||||||
$this->driver::create($statistic->toArray())
|
|
||||||
)); */
|
|
||||||
|
|
||||||
$currentConnectionCount = $this->channelManager->getConnectionCount($appId);
|
$currentConnectionCount = $this->channelManager->getConnectionCount($appId);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue