Completed
Pull Request — master (#140)
by Alexandru
01:30
created

StartWebSocketServer::configurePubSubReplication()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace BeyondCode\LaravelWebSockets\Console;
4
5
use BeyondCode\LaravelWebSockets\Facades\StatisticsLogger;
6
use BeyondCode\LaravelWebSockets\Facades\WebSocketsRouter;
7
use BeyondCode\LaravelWebSockets\PubSub\ReplicationInterface;
8
use BeyondCode\LaravelWebSockets\Server\Logger\ConnectionLogger;
9
use BeyondCode\LaravelWebSockets\Server\Logger\HttpLogger;
10
use BeyondCode\LaravelWebSockets\Server\Logger\WebsocketsLogger;
11
use BeyondCode\LaravelWebSockets\Server\WebSocketServerFactory;
12
use BeyondCode\LaravelWebSockets\Statistics\DnsResolver;
13
use BeyondCode\LaravelWebSockets\Statistics\Logger\HttpStatisticsLogger;
14
use BeyondCode\LaravelWebSockets\Statistics\Logger\StatisticsLogger as StatisticsLoggerInterface;
15
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
16
use Clue\React\Buzz\Browser;
17
use Illuminate\Console\Command;
18
use React\Dns\Config\Config as DnsConfig;
19
use React\Dns\Resolver\Factory as DnsFactory;
20
use React\Dns\Resolver\ResolverInterface;
21
use React\EventLoop\Factory as LoopFactory;
22
use React\Socket\Connector;
23
24
class StartWebSocketServer extends Command
25
{
26
    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 } ';
27
28
    protected $description = 'Start the Laravel WebSocket Server';
29
30
    /** @var \React\EventLoop\LoopInterface */
31
    protected $loop;
32
33
    public function __construct()
34
    {
35
        parent::__construct();
36
37
        $this->loop = LoopFactory::create();
38
    }
39
40
    public function handle()
41
    {
42
        $this
43
            ->configureStatisticsLogger()
44
            ->configureHttpLogger()
45
            ->configureMessageLogger()
46
            ->configureConnectionLogger()
47
            ->registerEchoRoutes()
48
            ->registerCustomRoutes()
49
            ->configurePubSubReplication()
50
            ->startWebSocketServer();
51
    }
52
53
    protected function configureStatisticsLogger()
54
    {
55
        $connector = new Connector($this->loop, [
56
            'dns' => $this->getDnsResolver(),
57
            'tls' => [
58
                'verify_peer' => config('app.env') === 'production',
59
                'verify_peer_name' => config('app.env') === 'production',
60
            ],
61
        ]);
62
63
        $browser = new Browser($this->loop, $connector);
64
65
        $this->laravel->singleton(StatisticsLoggerInterface::class, function () use ($browser) {
66
            return new HttpStatisticsLogger($this->laravel->make(ChannelManager::class), $browser);
67
        });
68
69
        $this->loop->addPeriodicTimer(config('websockets.statistics.interval_in_seconds'), function () {
70
            StatisticsLogger::save();
71
        });
72
73
        return $this;
74
    }
75
76 View Code Duplication
    protected function configureHttpLogger()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
77
    {
78
        $this->laravel->singleton(HttpLogger::class, function () {
79
            return (new HttpLogger($this->output))
80
                ->enable($this->option('debug') ?: config('app.debug'))
81
                ->verbose($this->output->isVerbose());
82
        });
83
84
        return $this;
85
    }
86
87 View Code Duplication
    protected function configureMessageLogger()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
88
    {
89
        $this->laravel->singleton(WebsocketsLogger::class, function () {
90
            return (new WebsocketsLogger($this->output))
91
                ->enable($this->option('debug') ?: config('app.debug'))
92
                ->verbose($this->output->isVerbose());
93
        });
94
95
        return $this;
96
    }
97
98 View Code Duplication
    protected function configureConnectionLogger()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
99
    {
100
        $this->laravel->bind(ConnectionLogger::class, function () {
101
            return (new ConnectionLogger($this->output))
102
                ->enable(config('app.debug'))
103
                ->verbose($this->output->isVerbose());
104
        });
105
106
        return $this;
107
    }
108
109
    protected function registerEchoRoutes()
110
    {
111
        WebSocketsRouter::echo();
112
113
        return $this;
114
    }
115
116
    protected function registerCustomRoutes()
117
    {
118
        WebSocketsRouter::customRoutes();
119
120
        return $this;
121
    }
122
123
    protected function startWebSocketServer()
124
    {
125
        $this->info("Starting the WebSocket server on port {$this->option('port')}...");
126
127
        $routes = WebSocketsRouter::getRoutes();
128
129
        /* 🛰 Start the server 🛰  */
130
        (new WebSocketServerFactory())
131
            ->setLoop($this->loop)
132
            ->useRoutes($routes)
133
            ->setHost($this->option('host'))
134
            ->setPort($this->option('port'))
135
            ->setConsoleOutput($this->output)
136
            ->createServer()
137
            ->run();
138
    }
139
140
    protected function configurePubSubReplication()
141
    {
142
        $this->laravel->get(ReplicationInterface::class)->boot($this->loop);
143
144
        return $this;
145
    }
146
147
    protected function getDnsResolver(): ResolverInterface
148
    {
149
        if (! config('websockets.statistics.perform_dns_lookup')) {
150
            return new DnsResolver;
151
        }
152
153
        $dnsConfig = DnsConfig::loadSystemConfigBlocking();
154
155
        return (new DnsFactory)->createCached(
156
            $dnsConfig->nameservers
157
                ? reset($dnsConfig->nameservers)
158
                : '1.1.1.1',
159
            $this->loop
160
        );
161
    }
162
}
163