Passed
Push — master ( e0b916...9184fe )
by Albert
06:29 queued 04:25
created

HttpServiceProvider::configureSwooleServer()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 2
nop 0
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SwooleTW\Http;
4
5
use SwooleTW\Http\Helpers\FW;
6
use Illuminate\Queue\QueueManager;
7
use Illuminate\Contracts\Http\Kernel;
8
use Swoole\Http\Server as HttpServer;
9
use Illuminate\Support\ServiceProvider;
10
use SwooleTW\Http\Middleware\AccessLog;
11
use SwooleTW\Http\Server\Facades\Server;
12
use Illuminate\Database\DatabaseManager;
13
use SwooleTW\Http\Coroutine\MySqlConnection;
14
use SwooleTW\Http\Commands\HttpServerCommand;
15
use Swoole\Websocket\Server as WebsocketServer;
16
use SwooleTW\Http\Task\Connectors\SwooleTaskConnector;
17
use SwooleTW\Http\Coroutine\Connectors\ConnectorFactory;
18
19
/**
20
 * @codeCoverageIgnore
21
 */
22
abstract class HttpServiceProvider extends ServiceProvider
23
{
24
    /**
25
     * Indicates if loading of the provider is deferred.
26
     *
27
     * @var bool
28
     */
29
    protected $defer = false;
30
31
    /**
32
     * @var boolean
33
     */
34
    protected $isWebsocket = false;
35
36
    /**
37
     * @var \Swoole\Http\Server | \Swoole\Websocket\Server
38
     */
39
    protected static $server;
40
41
    /**
42
     * Register the service provider.
43
     *
44
     * @return void
45
     */
46
    public function register()
47
    {
48
        $this->mergeConfigs();
49
        $this->setIsWebsocket();
50
        $this->registerServer();
51
        $this->registerManager();
52
        $this->registerCommands();
53
        $this->registerDatabaseDriver();
54
        $this->registerSwooleQueueDriver();
55
    }
56
57
    /**
58
     * Register manager.
59
     *
60
     * @return void
61
     */
62
    abstract protected function registerManager();
63
64
    /**
65
     * Boot routes.
66
     *
67
     * @return void
68
     */
69
    abstract protected function bootRoutes();
70
71
    /**
72
     * Boot the service provider.
73
     *
74
     * @return void
75
     */
76
    public function boot()
77
    {
78
        $this->publishes([
79
            __DIR__ . '/../config/swoole_http.php' => base_path('config/swoole_http.php'),
80
            __DIR__ . '/../config/swoole_websocket.php' => base_path('config/swoole_websocket.php'),
81
            __DIR__ . '/../routes/websocket.php' => base_path('routes/websocket.php'),
82
        ], 'laravel-swoole');
83
84
        $config = $this->app->make('config');
85
86
        if ($config->get('swoole_http.websocket.enabled')) {
87
            $this->bootRoutes();
88
        }
89
90
        if ($config->get('swoole_http.server.access_log')) {
91
            $this->app->make(Kernel::class)->pushMiddleware(AccessLog::class);
0 ignored issues
show
Bug introduced by
The method pushMiddleware() does not exist on Illuminate\Contracts\Http\Kernel. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

91
            $this->app->make(Kernel::class)->/** @scrutinizer ignore-call */ pushMiddleware(AccessLog::class);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
92
        }
93
    }
94
95
    /**
96
     * Merge configurations.
97
     */
98
    protected function mergeConfigs()
99
    {
100
        $this->mergeConfigFrom(__DIR__ . '/../config/swoole_http.php', 'swoole_http');
101
        $this->mergeConfigFrom(__DIR__ . '/../config/swoole_websocket.php', 'swoole_websocket');
102
    }
103
104
    /**
105
     * Set isWebsocket.
106
     */
107
    protected function setIsWebsocket()
108
    {
109
        $this->isWebsocket = $this->app->make('config')
110
            ->get('swoole_http.websocket.enabled');
111
    }
112
113
    /**
114
     * Register commands.
115
     */
116
    protected function registerCommands()
117
    {
118
        $this->commands([
119
            HttpServerCommand::class,
120
        ]);
121
    }
122
123
    /**
124
     * Create swoole server.
125
     */
126
    protected function createSwooleServer()
127
    {
128
        $server = $this->isWebsocket ? WebsocketServer::class : HttpServer::class;
129
        $config = $this->app->make('config');
130
        $host = $config->get('swoole_http.server.host');
131
        $port = $config->get('swoole_http.server.port');
132
        $socketType = $config->get('swoole_http.server.socket_type', SWOOLE_SOCK_TCP);
133
        $processType = $config->get('swoole.http.server.process_type', SWOOLE_PROCESS);
134
135
        static::$server = new $server($host, $port, $processType, $socketType);
136
    }
137
138
    /**
139
     * Set swoole server configurations.
140
     */
141
    protected function configureSwooleServer()
142
    {
143
        $config = $this->app->make('config');
144
        $options = $config->get('swoole_http.server.options');
145
146
        // only enable task worker in websocket mode and for queue driver
147
        if ($config->get('queue.default') !== 'swoole' && ! $this->isWebsocket) {
148
            unset($config['task_worker_num']);
149
        }
150
151
        static::$server->set($options);
152
    }
153
154
    /**
155
     * Register manager.
156
     *
157
     * @return void
158
     */
159
    protected function registerServer()
160
    {
161
        $this->app->singleton(Server::class, function () {
162
            if (is_null(static::$server)) {
163
                $this->createSwooleServer();
164
                $this->configureSwooleServer();
165
            }
166
167
            return static::$server;
168
        });
169
        $this->app->alias(Server::class, 'swoole.server');
170
    }
171
172
    /**
173
     * Register database driver for coroutine mysql.
174
     */
175
    protected function registerDatabaseDriver()
176
    {
177
        $this->app->extend(DatabaseManager::class, function (DatabaseManager $db) {
178
            $db->extend('mysql-coroutine', function ($config, $name) {
179
                $config['name'] = $name;
180
181
                $connection = new MySqlConnection(
182
                    $this->getNewMySqlConnection($config, 'write'),
183
                    $config['database'],
184
                    $config['prefix'],
185
                    $config
186
                );
187
188
                if (isset($config['read'])) {
189
                    $connection->setReadPdo($this->getNewMySqlConnection($config, 'read'));
190
                }
191
192
                return $connection;
193
            });
194
195
            return $db;
196
        });
197
    }
198
199
    /**
200
     * Get a new mysql connection.
201
     *
202
     * @param array $config
203
     * @param string $connection
204
     *
205
     * @return \PDO
206
     */
207
    protected function getNewMySqlConnection(array $config, string $connection = null)
208
    {
209
        if ($connection && isset($config[$connection])) {
210
            $config = array_merge($config, $config[$connection]);
211
        }
212
213
        return ConnectorFactory::make(FW::version())->connect($config);
214
    }
215
216
    /**
217
     * Register queue driver for swoole async task.
218
     */
219
    protected function registerSwooleQueueDriver()
220
    {
221
        $this->app->afterResolving('queue', function (QueueManager $manager) {
222
            $manager->addConnector('swoole', function () {
223
                return new SwooleTaskConnector($this->app->make(Server::class));
0 ignored issues
show
Bug introduced by
$this->app->make(SwooleT...\Facades\Server::class) of type SwooleTW\Http\Server\Facades\Server is incompatible with the type Swoole\Http\Server expected by parameter $swoole of SwooleTW\Http\Task\Conne...onnector::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

223
                return new SwooleTaskConnector(/** @scrutinizer ignore-type */ $this->app->make(Server::class));
Loading history...
224
            });
225
        });
226
    }
227
}
228