laravel-websockets/src/Console/StartWebSocketServer.php

172 lines
5.2 KiB
PHP
Raw Normal View History

2018-11-20 10:51:00 +00:00
<?php
2018-11-21 11:13:40 +00:00
namespace BeyondCode\LaravelWebSockets\Console;
2018-11-20 10:51:00 +00:00
2018-12-04 21:22:33 +00:00
use React\Socket\Connector;
use Clue\React\Buzz\Browser;
use Illuminate\Console\Command;
use React\Dns\Config\Config as DnsConfig;
use React\Dns\Resolver\ResolverInterface;
2018-12-04 21:22:33 +00:00
use React\EventLoop\Factory as LoopFactory;
use React\Dns\Resolver\Factory as DnsFactory;
use BeyondCode\LaravelWebSockets\Statistics\DnsResolver;
2018-12-03 12:33:20 +00:00
use BeyondCode\LaravelWebSockets\Facades\StatisticsLogger;
2018-11-30 14:51:30 +00:00
use BeyondCode\LaravelWebSockets\Facades\WebSocketsRouter;
use BeyondCode\LaravelWebSockets\PubSub\Redis\RedisClient;
2018-11-27 20:30:33 +00:00
use BeyondCode\LaravelWebSockets\Server\Logger\HttpLogger;
2019-03-25 22:37:14 +00:00
use BeyondCode\LaravelWebSockets\PubSub\ReplicationInterface;
2018-12-04 21:22:33 +00:00
use BeyondCode\LaravelWebSockets\Server\WebSocketServerFactory;
use BeyondCode\LaravelWebSockets\Server\Logger\ConnectionLogger;
2018-11-30 14:52:11 +00:00
use BeyondCode\LaravelWebSockets\Server\Logger\WebsocketsLogger;
2018-12-04 21:22:33 +00:00
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
2018-12-03 15:29:47 +00:00
use BeyondCode\LaravelWebSockets\Statistics\Logger\HttpStatisticsLogger;
use BeyondCode\LaravelWebSockets\Statistics\Logger\StatisticsLogger as StatisticsLoggerInterface;
2018-11-20 10:51:00 +00:00
class StartWebSocketServer extends Command
{
2018-12-05 14:00:21 +00:00
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 } ';
2018-11-20 10:51:00 +00:00
protected $description = 'Start the Laravel WebSocket Server';
2018-12-03 12:33:20 +00:00
/** @var \React\EventLoop\LoopInterface */
protected $loop;
public function __construct()
{
parent::__construct();
$this->loop = LoopFactory::create();
}
2018-11-20 10:51:00 +00:00
public function handle()
{
2018-11-24 00:25:40 +00:00
$this
2018-12-03 12:33:20 +00:00
->configureStatisticsLogger()
2018-11-27 20:30:33 +00:00
->configureHttpLogger()
2018-11-24 14:23:59 +00:00
->configureMessageLogger()
->configureConnectionLogger()
2018-11-24 00:25:40 +00:00
->registerEchoRoutes()
->registerCustomRoutes()
->configurePubSubReplication()
2018-11-24 00:25:40 +00:00
->startWebSocketServer();
}
2018-12-03 13:46:51 +00:00
protected function configureStatisticsLogger()
{
2018-12-03 20:44:43 +00:00
$connector = new Connector($this->loop, [
'dns' => $this->getDnsResolver(),
'tls' => [
'verify_peer' => config('app.env') === 'production',
2018-12-05 20:10:08 +00:00
'verify_peer_name' => config('app.env') === 'production',
],
2018-12-03 20:44:43 +00:00
]);
2018-12-03 13:46:51 +00:00
2018-12-03 20:06:49 +00:00
$browser = new Browser($this->loop, $connector);
2018-12-03 13:46:51 +00:00
2018-12-04 21:22:33 +00:00
app()->singleton(StatisticsLoggerInterface::class, function () use ($browser) {
2018-12-03 20:06:49 +00:00
return new HttpStatisticsLogger(app(ChannelManager::class), $browser);
2018-12-03 13:46:51 +00:00
});
2018-12-04 21:22:33 +00:00
$this->loop->addPeriodicTimer(config('websockets.statistics.interval_in_seconds'), function () {
2018-12-03 20:02:21 +00:00
StatisticsLogger::save();
2018-12-03 13:46:51 +00:00
});
return $this;
}
2018-11-27 20:30:33 +00:00
protected function configureHttpLogger()
{
2018-12-04 21:22:33 +00:00
app()->singleton(HttpLogger::class, function () {
2018-11-27 20:30:33 +00:00
return (new HttpLogger($this->output))
2018-12-05 13:56:01 +00:00
->enable($this->option('debug') ?: config('app.debug'))
2018-11-27 20:30:33 +00:00
->verbose($this->output->isVerbose());
});
return $this;
}
2018-11-24 14:23:59 +00:00
protected function configureMessageLogger()
2018-11-24 00:25:40 +00:00
{
2018-12-04 21:22:33 +00:00
app()->singleton(WebsocketsLogger::class, function () {
2018-11-30 14:52:11 +00:00
return (new WebsocketsLogger($this->output))
2018-12-05 13:56:01 +00:00
->enable($this->option('debug') ?: config('app.debug'))
2018-11-26 07:55:08 +00:00
->verbose($this->output->isVerbose());
2018-11-24 14:23:59 +00:00
});
return $this;
}
protected function configureConnectionLogger()
{
2018-12-04 21:22:33 +00:00
app()->bind(ConnectionLogger::class, function () {
2018-11-24 14:23:59 +00:00
return (new ConnectionLogger($this->output))
2018-11-24 00:25:40 +00:00
->enable(config('app.debug'))
2018-11-26 07:55:08 +00:00
->verbose($this->output->isVerbose());
2018-11-24 00:25:40 +00:00
});
2018-11-22 07:49:26 +00:00
2018-11-24 00:25:40 +00:00
return $this;
}
protected function registerEchoRoutes()
{
2018-11-30 14:51:30 +00:00
WebSocketsRouter::echo();
2018-11-22 07:49:26 +00:00
2018-11-24 00:25:40 +00:00
return $this;
2018-11-22 07:49:26 +00:00
}
protected function registerCustomRoutes()
{
WebSocketsRouter::customRoutes();
return $this;
}
2018-11-24 00:25:40 +00:00
protected function startWebSocketServer()
2018-11-22 07:49:26 +00:00
{
2018-11-24 00:35:08 +00:00
$this->info("Starting the WebSocket server on port {$this->option('port')}...");
2018-11-20 10:51:00 +00:00
2018-11-30 14:51:30 +00:00
$routes = WebSocketsRouter::getRoutes();
2018-11-20 10:51:00 +00:00
2018-12-04 21:22:33 +00:00
/* 🛰 Start the server 🛰 */
2018-11-27 20:53:50 +00:00
(new WebSocketServerFactory())
2018-12-03 12:33:20 +00:00
->setLoop($this->loop)
2018-11-27 20:53:50 +00:00
->useRoutes($routes)
2018-11-22 07:49:26 +00:00
->setHost($this->option('host'))
->setPort($this->option('port'))
2018-11-23 21:46:09 +00:00
->setConsoleOutput($this->output)
2018-11-27 20:53:50 +00:00
->createServer()
2018-11-24 00:25:40 +00:00
->run();
2018-11-20 10:51:00 +00:00
}
protected function configurePubSubReplication()
{
if (config('websockets.replication.enabled') !== true) {
return $this;
}
if (config('websockets.replication.driver') === 'redis') {
app()->singleton(ReplicationInterface::class, function () {
return (new RedisClient())->boot($this->loop);
});
}
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
);
}
2018-11-24 00:25:40 +00:00
}