loop = LoopFactory::create(); } public function handle() { $this ->configureStatisticsLogger() ->configureHttpLogger() ->configureMessageLogger() ->configureConnectionLogger() ->registerEchoRoutes() ->registerCustomRoutes() ->configurePubSubReplication() ->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) { return new HttpStatisticsLogger(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; } 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 configurePubSubReplication() { if (config('websockets.replication.enabled') !== true) { return $this; } if (config('websockets.replication.driver') === 'redis') { $connection = (new RedisClient())->subscribe($this->loop); } app()->singleton(PubSubInterface::class, function () use ($connection) { return $connection; }); return $this; } 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 ); } }