Passed
Branch master (bd6415)
by Albert
05:36 queued 03:04
created

src/HttpServiceProvider.php (1 issue)

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

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

92
            $this->/** @scrutinizer ignore-call */ 
93
                   bootRoutes();

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