178 lines
5.2 KiB
PHP
178 lines
5.2 KiB
PHP
<?php
|
|
|
|
namespace BeyondCode\LaravelWebSockets\Console;
|
|
|
|
use BeyondCode\LaravelWebSockets\Facades\StatisticsLogger;
|
|
use BeyondCode\LaravelWebSockets\Facades\WebSocketsRouter;
|
|
use BeyondCode\LaravelWebSockets\Server\Logger\ConnectionLogger;
|
|
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\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
|
|
{
|
|
protected $signature = 'websockets:serve {--host=0.0.0.0} {--port=6001} {--debug : Forces the loggers to be enabled and thereby overriding the app.debug config setting } ';
|
|
|
|
protected $description = 'Start the Laravel WebSocket Server';
|
|
|
|
/** @var \React\EventLoop\LoopInterface */
|
|
protected $loop;
|
|
|
|
/** @var int */
|
|
protected $lastRestart;
|
|
|
|
public function __construct()
|
|
{
|
|
parent::__construct();
|
|
|
|
$this->loop = LoopFactory::create();
|
|
}
|
|
|
|
public function handle()
|
|
{
|
|
$this
|
|
->configureStatisticsLogger()
|
|
->configureHttpLogger()
|
|
->configureMessageLogger()
|
|
->configureConnectionLogger()
|
|
->configureRestartTimer()
|
|
->registerEchoRoutes()
|
|
->registerCustomRoutes()
|
|
->startWebSocketServer();
|
|
}
|
|
|
|
protected function configureStatisticsLogger()
|
|
{
|
|
$connector = new Connector($this->loop, [
|
|
'dns' => $this->getDnsResolver(),
|
|
'tls' => [
|
|
'verify_peer' => config('app.env') === 'production',
|
|
'verify_peer_name' => config('app.env') === 'production',
|
|
],
|
|
]);
|
|
|
|
$browser = new Browser($this->loop, $connector);
|
|
|
|
app()->singleton(StatisticsLoggerInterface::class, function () use ($browser) {
|
|
$class = config('websockets.statistics.logger', \BeyondCode\LaravelWebSockets\Statistics\Logger::class);
|
|
|
|
return new $class(app(ChannelManager::class), $browser);
|
|
});
|
|
|
|
$this->loop->addPeriodicTimer(config('websockets.statistics.interval_in_seconds'), function () {
|
|
StatisticsLogger::save();
|
|
});
|
|
|
|
return $this;
|
|
}
|
|
|
|
protected function configureHttpLogger()
|
|
{
|
|
app()->singleton(HttpLogger::class, function () {
|
|
return (new HttpLogger($this->output))
|
|
->enable($this->option('debug') ?: config('app.debug'))
|
|
->verbose($this->output->isVerbose());
|
|
});
|
|
|
|
return $this;
|
|
}
|
|
|
|
protected function configureMessageLogger()
|
|
{
|
|
app()->singleton(WebsocketsLogger::class, function () {
|
|
return (new WebsocketsLogger($this->output))
|
|
->enable($this->option('debug') ?: config('app.debug'))
|
|
->verbose($this->output->isVerbose());
|
|
});
|
|
|
|
return $this;
|
|
}
|
|
|
|
protected function configureConnectionLogger()
|
|
{
|
|
app()->bind(ConnectionLogger::class, function () {
|
|
return (new ConnectionLogger($this->output))
|
|
->enable(config('app.debug'))
|
|
->verbose($this->output->isVerbose());
|
|
});
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function configureRestartTimer()
|
|
{
|
|
$this->lastRestart = $this->getLastRestart();
|
|
|
|
$this->loop->addPeriodicTimer(10, function () {
|
|
if ($this->getLastRestart() !== $this->lastRestart) {
|
|
$this->loop->stop();
|
|
}
|
|
});
|
|
|
|
return $this;
|
|
}
|
|
|
|
protected function registerEchoRoutes()
|
|
{
|
|
WebSocketsRouter::echo();
|
|
|
|
return $this;
|
|
}
|
|
|
|
protected function registerCustomRoutes()
|
|
{
|
|
WebSocketsRouter::customRoutes();
|
|
|
|
return $this;
|
|
}
|
|
|
|
protected function startWebSocketServer()
|
|
{
|
|
$this->info("Starting the WebSocket server on port {$this->option('port')}...");
|
|
|
|
$routes = WebSocketsRouter::getRoutes();
|
|
|
|
/* 🛰 Start the server 🛰 */
|
|
(new WebSocketServerFactory())
|
|
->setLoop($this->loop)
|
|
->useRoutes($routes)
|
|
->setHost($this->option('host'))
|
|
->setPort($this->option('port'))
|
|
->setConsoleOutput($this->output)
|
|
->createServer()
|
|
->run();
|
|
}
|
|
|
|
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
|
|
);
|
|
}
|
|
|
|
protected function getLastRestart()
|
|
{
|
|
return Cache::get('beyondcode:websockets:restart', 0);
|
|
}
|
|
}
|