Passed
Push — master ( 0f36ee...b3b9d5 )
by Albert
05:07 queued 02:26
created

HttpServiceProvider::publishFiles()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 0
dl 0
loc 7
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 SwooleTW\Http\Server\PidManager;
8
use Swoole\Http\Server as HttpServer;
9
use Illuminate\Support\ServiceProvider;
10
use Illuminate\Database\DatabaseManager;
11
use SwooleTW\Http\Server\Facades\Server;
12
use SwooleTW\Http\Coroutine\MySqlConnection;
13
use SwooleTW\Http\Commands\HttpServerCommand;
14
use Swoole\Websocket\Server as WebsocketServer;
15
use SwooleTW\Http\Task\Connectors\SwooleTaskConnector;
16
use SwooleTW\Http\Coroutine\Connectors\ConnectorFactory;
17
18
/**
19
 * @codeCoverageIgnore
20
 */
21
abstract class HttpServiceProvider extends ServiceProvider
22
{
23
    /**
24
     * Indicates if loading of the provider is deferred.
25
     *
26
     * @var bool
27
     */
28
    protected $defer = false;
29
30
    /**
31
     * @var boolean
32
     */
33
    protected $isWebsocket = false;
34
35
    /**
36
     * @var \Swoole\Http\Server | \Swoole\Websocket\Server
37
     */
38
    protected static $server;
39
40
    /**
41
     * Boot the service provider.
42
     *
43
     * @return void
44
     */
45
    public function boot()
46
    {
47
        $this->publishFiles();
48
        $this->loadConfigs();
49
        $this->mergeConfigs();
50
        $this->setIsWebsocket();
51
52
        $config = $this->app->make('config');
53
54
        if ($config->get('swoole_http.websocket.enabled')) {
55
            $this->bootWebsocketRoutes();
56
        }
57
58
        if ($config->get('swoole_http.server.access_log')) {
59
            $this->pushAccessLogMiddleware();
60
        }
61
    }
62
63
    /**
64
     * Register the service provider.
65
     *
66
     * @return void
67
     */
68
    public function register()
69
    {
70
        $this->registerServer();
71
        $this->registerManager();
72
        $this->registerCommands();
73
        $this->registerPidManager();
74
        $this->registerDatabaseDriver();
75
        $this->registerSwooleQueueDriver();
76
    }
77
78
    /**
79
     * Register manager.
80
     *
81
     * @return void
82
     */
83
    abstract protected function registerManager();
84
85
    /**
86
     * Boot websocket routes.
87
     *
88
     * @return void
89
     */
90
    abstract protected function bootWebsocketRoutes();
91
92
    /**
93
     * Register access log middleware to container.
94
     *
95
     * @return void
96
     */
97
    abstract protected function pushAccessLogMiddleware();
98
99
    /**
100
     * Publish files of this package.
101
     */
102
    protected function publishFiles()
103
    {
104
        $this->publishes([
105
            __DIR__ . '/../config/swoole_http.php' => base_path('config/swoole_http.php'),
106
            __DIR__ . '/../config/swoole_websocket.php' => base_path('config/swoole_websocket.php'),
107
            __DIR__ . '/../routes/websocket.php' => base_path('routes/websocket.php'),
108
        ], 'laravel-swoole');
109
    }
110
111
    /**
112
     * Load configurations.
113
     */
114
    protected function loadConfigs()
115
    {
116
        // do nothing
117
    }
118
119
    /**
120
     * Merge configurations.
121
     */
122
    protected function mergeConfigs()
123
    {
124
        $this->mergeConfigFrom(__DIR__ . '/../config/swoole_http.php', 'swoole_http');
125
        $this->mergeConfigFrom(__DIR__ . '/../config/swoole_websocket.php', 'swoole_websocket');
126
    }
127
128
    /**
129
     * Register pid manager.
130
     *
131
     * @return void
132
     */
133
    protected function registerPidManager(): void
134
    {
135
        $this->app->singleton(PidManager::class, function() {
136
            return new PidManager(
137
                $this->app->make('config')->get('swoole_http.server.options.pid_file')
138
            );
139
        });
140
    }
141
142
    /**
143
     * Set isWebsocket.
144
     */
145
    protected function setIsWebsocket()
146
    {
147
        $this->isWebsocket = $this->app->make('config')
148
            ->get('swoole_http.websocket.enabled');
149
    }
150
151
    /**
152
     * Register commands.
153
     */
154
    protected function registerCommands()
155
    {
156
        $this->commands([
157
            HttpServerCommand::class,
158
        ]);
159
    }
160
161
    /**
162
     * Create swoole server.
163
     */
164
    protected function createSwooleServer()
165
    {
166
        $server = $this->isWebsocket ? WebsocketServer::class : HttpServer::class;
167
        $config = $this->app->make('config');
168
        $host = $config->get('swoole_http.server.host');
169
        $port = $config->get('swoole_http.server.port');
170
        $socketType = $config->get('swoole_http.server.socket_type', SWOOLE_SOCK_TCP);
171
        $processType = $config->get('swoole_http.server.process_type', SWOOLE_PROCESS);
172
173
        static::$server = new $server($host, $port, $processType, $socketType);
174
    }
175
176
    /**
177
     * Set swoole server configurations.
178
     */
179
    protected function configureSwooleServer()
180
    {
181
        $config = $this->app->make('config');
182
        $options = $config->get('swoole_http.server.options');
183
184
        // only enable task worker in websocket mode and for queue driver
185
        if ($config->get('queue.default') !== 'swoole' && ! $this->isWebsocket) {
186
            unset($options['task_worker_num']);
187
        }
188
189
        static::$server->set($options);
190
    }
191
192
    /**
193
     * Register manager.
194
     *
195
     * @return void
196
     */
197
    protected function registerServer()
198
    {
199
        $this->app->singleton(Server::class, function () {
200
            if (is_null(static::$server)) {
201
                $this->createSwooleServer();
202
                $this->configureSwooleServer();
203
            }
204
205
            return static::$server;
206
        });
207
        $this->app->alias(Server::class, 'swoole.server');
208
    }
209
210
    /**
211
     * Register database driver for coroutine mysql.
212
     */
213
    protected function registerDatabaseDriver()
214
    {
215
        $this->app->extend(DatabaseManager::class, function (DatabaseManager $db) {
216
            $db->extend('mysql-coroutine', function ($config, $name) {
217
                $config['name'] = $name;
218
219
                $connection = new MySqlConnection(
220
                    $this->getNewMySqlConnection($config, 'write'),
221
                    $config['database'],
222
                    $config['prefix'],
223
                    $config
224
                );
225
226
                if (isset($config['read'])) {
227
                    $connection->setReadPdo($this->getNewMySqlConnection($config, 'read'));
228
                }
229
230
                return $connection;
231
            });
232
233
            return $db;
234
        });
235
    }
236
237
    /**
238
     * Get a new mysql connection.
239
     *
240
     * @param array $config
241
     * @param string $connection
242
     *
243
     * @return \PDO
244
     */
245
    protected function getNewMySqlConnection(array $config, string $connection = null)
246
    {
247
        if ($connection && isset($config[$connection])) {
248
            $config = array_merge($config, $config[$connection]);
249
        }
250
251
        return ConnectorFactory::make(FW::version())->connect($config);
252
    }
253
254
    /**
255
     * Register queue driver for swoole async task.
256
     */
257
    protected function registerSwooleQueueDriver()
258
    {
259
        $this->app->afterResolving('queue', function (QueueManager $manager) {
260
            $manager->addConnector('swoole', function () {
261
                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

261
                return new SwooleTaskConnector(/** @scrutinizer ignore-type */ $this->app->make(Server::class));
Loading history...
262
            });
263
        });
264
    }
265
}
266