Merge pull request #475 from beyondcode/fix/memory-leaks

[fix] Memory Leaks
This commit is contained in:
rennokki 2020-08-21 15:27:10 +03:00 committed by GitHub
commit a08eee60e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 137 additions and 323 deletions

View File

@ -239,37 +239,6 @@ return [
'delete_statistics_older_than_days' => 60, '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',
],
], ],
]; ];

View File

@ -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>

View File

@ -11,17 +11,12 @@ use BeyondCode\LaravelWebSockets\Server\Logger\ConnectionLogger;
use BeyondCode\LaravelWebSockets\Server\Logger\HttpLogger; use BeyondCode\LaravelWebSockets\Server\Logger\HttpLogger;
use BeyondCode\LaravelWebSockets\Server\Logger\WebsocketsLogger; use BeyondCode\LaravelWebSockets\Server\Logger\WebsocketsLogger;
use BeyondCode\LaravelWebSockets\Server\WebSocketServerFactory; 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\Statistics\Logger\StatisticsLogger as StatisticsLoggerInterface;
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager; use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
use Clue\React\Buzz\Browser;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Facades\Cache; 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\EventLoop\Factory as LoopFactory;
use React\Socket\Connector;
class StartWebSocketServer extends Command class StartWebSocketServer extends Command
{ {
@ -103,19 +98,12 @@ class StartWebSocketServer extends Command
*/ */
protected function configureStatisticsLogger() protected function configureStatisticsLogger()
{ {
$connector = new Connector($this->loop, [ $this->laravel->singleton(StatisticsLoggerInterface::class, function () {
'dns' => $this->getDnsResolver(),
'tls' => config('websockets.statistics.tls'),
]);
$browser = new Browser($this->loop, $connector);
$this->laravel->singleton(StatisticsLoggerInterface::class, function () use ($browser) {
$class = config('websockets.statistics.logger', \BeyondCode\LaravelWebSockets\Statistics\Logger\MemoryStatisticsLogger::class); $class = config('websockets.statistics.logger', \BeyondCode\LaravelWebSockets\Statistics\Logger\MemoryStatisticsLogger::class);
return new $class( return new $class(
$this->laravel->make(ChannelManager::class), $this->laravel->make(ChannelManager::class),
$browser $this->laravel->make(StatisticsDriver::class)
); );
}); });
@ -273,27 +261,6 @@ class StartWebSocketServer extends Command
->createServer(); ->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. * Get the last time the server restarted.
* *

View File

@ -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'),
],
];
} }
} }

View File

@ -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'),
]); ]);
} }
} }

View File

@ -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

View File

@ -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

View File

@ -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';
}
}

View File

@ -1,34 +0,0 @@
<?php
namespace BeyondCode\LaravelWebSockets\Statistics\Http\Controllers;
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
use BeyondCode\LaravelWebSockets\Statistics\Events\StatisticsUpdated;
use BeyondCode\LaravelWebSockets\Statistics\Rules\AppId;
use Illuminate\Http\Request;
class WebSocketStatisticsEntriesController
{
/**
* Store the entry.
*
* @param \Illuminate\Http\Request $request
* @param \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver $driver
* @return \Illuminate\Http\Response
*/
public function store(Request $request, StatisticsDriver $driver)
{
$validatedAttributes = $request->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';
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace BeyondCode\LaravelWebSockets\Statistics\Http\Middleware;
use BeyondCode\LaravelWebSockets\Apps\App;
class Authorize
{
/**
* Authorize the request by app secret.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return \Illuminate\Http\Response
*/
public function handle($request, $next)
{
return is_null(App::findBySecret($request->secret))
? abort(403)
: $next($request);
}
}

View File

@ -3,11 +3,9 @@
namespace BeyondCode\LaravelWebSockets\Statistics\Logger; namespace BeyondCode\LaravelWebSockets\Statistics\Logger;
use BeyondCode\LaravelWebSockets\Apps\App; 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\Statistics\Statistic;
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager; use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
use Clue\React\Buzz\Browser;
use function GuzzleHttp\Psr7\stream_for;
use Ratchet\ConnectionInterface; use Ratchet\ConnectionInterface;
class MemoryStatisticsLogger implements StatisticsLogger class MemoryStatisticsLogger implements StatisticsLogger
@ -27,23 +25,23 @@ class MemoryStatisticsLogger implements StatisticsLogger
protected $channelManager; 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. * Initialize the logger.
* *
* @param \BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager $channelManager * @param \BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager $channelManager
* @param \Clue\React\Buzz\Browser $browser * @param \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver $driver
* @return void * @return void
*/ */
public function __construct(ChannelManager $channelManager, Browser $browser) public function __construct(ChannelManager $channelManager, StatisticsDriver $driver)
{ {
$this->channelManager = $channelManager; $this->channelManager = $channelManager;
$this->browser = $browser; $this->driver = $driver;
} }
/** /**
@ -106,16 +104,7 @@ class MemoryStatisticsLogger implements StatisticsLogger
continue; continue;
} }
$postData = array_merge($statistic->toArray(), [ $this->driver::create($statistic->toArray());
'secret' => App::findById($appId)->secret,
]);
$this->browser
->post(
action([WebSocketStatisticsEntriesController::class, 'store']),
['Content-Type' => 'application/json'],
stream_for(json_encode($postData))
);
$currentConnectionCount = $this->channelManager->getConnectionCount($appId); $currentConnectionCount = $this->channelManager->getConnectionCount($appId);

View File

@ -2,8 +2,8 @@
namespace BeyondCode\LaravelWebSockets\Statistics\Logger; namespace BeyondCode\LaravelWebSockets\Statistics\Logger;
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager; use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
use Clue\React\Buzz\Browser;
use Ratchet\ConnectionInterface; use Ratchet\ConnectionInterface;
class NullStatisticsLogger implements StatisticsLogger class NullStatisticsLogger implements StatisticsLogger
@ -16,23 +16,23 @@ class NullStatisticsLogger implements StatisticsLogger
protected $channelManager; 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. * Initialize the logger.
* *
* @param \BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager $channelManager * @param \BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager $channelManager
* @param \Clue\React\Buzz\Browser $browser * @param \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver $driver
* @return void * @return void
*/ */
public function __construct(ChannelManager $channelManager, Browser $browser) public function __construct(ChannelManager $channelManager, StatisticsDriver $driver)
{ {
$this->channelManager = $channelManager; $this->channelManager = $channelManager;
$this->browser = $browser; $this->driver = $driver;
} }
/** /**

View File

@ -11,8 +11,6 @@ use BeyondCode\LaravelWebSockets\Dashboard\Http\Middleware\Authorize as Authoriz
use BeyondCode\LaravelWebSockets\PubSub\Broadcasters\RedisPusherBroadcaster; use BeyondCode\LaravelWebSockets\PubSub\Broadcasters\RedisPusherBroadcaster;
use BeyondCode\LaravelWebSockets\Server\Router; use BeyondCode\LaravelWebSockets\Server\Router;
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver; 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\ChannelManager;
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManagers\ArrayChannelManager; use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManagers\ArrayChannelManager;
use Illuminate\Broadcasting\BroadcastManager; use Illuminate\Broadcasting\BroadcastManager;
@ -127,10 +125,6 @@ class WebSocketsServiceProvider extends ServiceProvider
Route::post('auth', AuthenticateDashboard::class); Route::post('auth', AuthenticateDashboard::class);
Route::post('event', SendMessage::class); Route::post('event', SendMessage::class);
}); });
Route::middleware(AuthorizeStatistics::class)->group(function () {
Route::post('statistics', [WebSocketStatisticsEntriesController::class, 'store']);
});
}); });
return $this; return $this;

View File

@ -1,42 +0,0 @@
<?php
namespace BeyondCode\LaravelWebSockets\Tests\Statistics\Controllers;
use BeyondCode\LaravelWebSockets\Statistics\Http\Controllers\WebSocketStatisticsEntriesController;
use BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry;
use BeyondCode\LaravelWebSockets\Tests\TestCase;
class WebSocketsStatisticsControllerTest extends TestCase
{
/** @test */
public function it_can_store_statistics()
{
$this->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',
];
}
}

View File

@ -6,13 +6,12 @@ use BeyondCode\LaravelWebSockets\Facades\StatisticsLogger;
use BeyondCode\LaravelWebSockets\PubSub\Drivers\LocalClient; use BeyondCode\LaravelWebSockets\PubSub\Drivers\LocalClient;
use BeyondCode\LaravelWebSockets\PubSub\Drivers\RedisClient; use BeyondCode\LaravelWebSockets\PubSub\Drivers\RedisClient;
use BeyondCode\LaravelWebSockets\PubSub\ReplicationInterface; use BeyondCode\LaravelWebSockets\PubSub\ReplicationInterface;
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
use BeyondCode\LaravelWebSockets\Tests\Mocks\Connection; use BeyondCode\LaravelWebSockets\Tests\Mocks\Connection;
use BeyondCode\LaravelWebSockets\Tests\Mocks\Message; use BeyondCode\LaravelWebSockets\Tests\Mocks\Message;
use BeyondCode\LaravelWebSockets\Tests\Statistics\Logger\FakeStatisticsLogger; use BeyondCode\LaravelWebSockets\Tests\Statistics\Logger\FakeStatisticsLogger;
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager; use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
use Clue\React\Buzz\Browser;
use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Request;
use Mockery;
use Ratchet\ConnectionInterface; use Ratchet\ConnectionInterface;
use React\EventLoop\Factory as LoopFactory; use React\EventLoop\Factory as LoopFactory;
@ -45,7 +44,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
StatisticsLogger::swap(new FakeStatisticsLogger( StatisticsLogger::swap(new FakeStatisticsLogger(
$this->channelManager, $this->channelManager,
Mockery::mock(Browser::class) app(StatisticsDriver::class)
)); ));
$this->loadMigrationsFrom(__DIR__.'/../database/migrations'); $this->loadMigrationsFrom(__DIR__.'/../database/migrations');
@ -94,8 +93,6 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
], ],
]); ]);
$app['config']->set('websockets.statistics.perform_dns_lookup', true);
$app['config']->set('database.redis.default', [ $app['config']->set('database.redis.default', [
'host' => env('REDIS_HOST', '127.0.0.1'), 'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null), 'password' => env('REDIS_PASSWORD', null),