| Total Complexity | 44 |
| Total Lines | 257 |
| Duplicated Lines | 0 % |
| Changes | 9 | ||
| Bugs | 2 | Features | 0 |
Complex classes like LaravelS often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use LaravelS, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 36 | class LaravelS extends Server |
||
| 37 | { |
||
| 38 | /** |
||
| 39 | * Fix conflicts of traits |
||
| 40 | */ |
||
| 41 | use InotifyTrait, ChokidarWatchTrait, LaravelTrait, LogTrait, ProcessTitleTrait, TimerTrait, CustomProcessTrait; |
||
| 42 | |||
| 43 | /**@var array */ |
||
| 44 | protected $laravelConf; |
||
| 45 | |||
| 46 | /**@var Laravel */ |
||
| 47 | protected $laravel; |
||
| 48 | |||
| 49 | public function __construct(array $svrConf, array $laravelConf) |
||
| 50 | { |
||
| 51 | parent::__construct($svrConf); |
||
| 52 | $this->laravelConf = $laravelConf; |
||
| 53 | |||
| 54 | $timerConf = isset($this->conf['timer']) ? $this->conf['timer'] : []; |
||
| 55 | $timerConf['process_prefix'] = $svrConf['process_prefix']; |
||
| 56 | $this->swoole->timerProcess = $this->addTimerProcess($this->swoole, $timerConf, $this->laravelConf); |
||
| 57 | |||
| 58 | $inotifyConf = isset($this->conf['inotify_reload']) ? $this->conf['inotify_reload'] : []; |
||
| 59 | if (!isset($inotifyConf['watch_path'])) { |
||
| 60 | $inotifyConf['watch_path'] = $this->laravelConf['root_path']; |
||
| 61 | } |
||
| 62 | $inotifyConf['process_prefix'] = $svrConf['process_prefix']; |
||
| 63 | $this->swoole->inotifyProcess = $this->addInotifyProcess($this->swoole, $inotifyConf, $this->laravelConf); |
||
| 64 | |||
| 65 | $chokidarConf = isset($this->conf['chokidar_reload']) ? $this->conf['chokidar_reload'] : []; |
||
| 66 | if (!empty($chokidarConf['enable'])) { |
||
| 67 | if (!isset($chokidarConf['watch_path'])) { |
||
| 68 | $chokidarConf['watch_path'] = $this->laravelConf['root_path']; |
||
| 69 | } |
||
| 70 | $chokidarConf['process_prefix'] = $svrConf['process_prefix']; |
||
| 71 | $this->swoole->chokidarProcess = $this->addChokidarWatchProcess($this->swoole, $chokidarConf, $this->laravelConf); |
||
| 72 | } |
||
| 73 | |||
| 74 | $processes = isset($this->conf['processes']) ? $this->conf['processes'] : []; |
||
| 75 | $this->swoole->customProcesses = $this->addCustomProcesses($this->swoole, $svrConf['process_prefix'], $processes, $this->laravelConf); |
||
| 76 | |||
| 77 | // Fire ServerStart event |
||
| 78 | if (isset($this->conf['event_handlers']['ServerStart'])) { |
||
| 79 | Laravel::autoload($this->laravelConf['root_path']); |
||
| 80 | $this->fireEvent('ServerStart', ServerStartInterface::class, [$this->swoole]); |
||
| 81 | } |
||
| 82 | } |
||
| 83 | |||
| 84 | protected function beforeWebSocketHandShake(SwooleRequest $request) |
||
| 85 | { |
||
| 86 | // Start Laravel's lifetime, then support session ...middleware. |
||
| 87 | $laravelRequest = $this->convertRequest($this->laravel, $request); |
||
| 88 | $this->laravel->bindRequest($laravelRequest); |
||
| 89 | $this->laravel->fireEvent('laravels.received_request', [$laravelRequest]); |
||
| 90 | $this->laravel->cleanProviders(); |
||
| 91 | $laravelResponse = $this->laravel->handleDynamic($laravelRequest); |
||
| 92 | $this->laravel->fireEvent('laravels.generated_response', [$laravelRequest, $laravelResponse]); |
||
| 93 | } |
||
| 94 | |||
| 95 | protected function afterWebSocketOpen(SwooleRequest $request) |
||
| 96 | { |
||
| 97 | // End Laravel's lifetime. |
||
| 98 | $this->laravel->saveSession(); |
||
| 99 | $this->laravel->clean(); |
||
| 100 | } |
||
| 101 | |||
| 102 | protected function triggerWebSocketEvent($event, array $params) |
||
| 103 | { |
||
| 104 | if ($event === 'onHandShake') { |
||
| 105 | $this->beforeWebSocketHandShake($params[0]); |
||
| 106 | if (!empty($this->conf['server'])) { |
||
| 107 | $params[1]->header('Server', $this->conf['server']); |
||
| 108 | } |
||
| 109 | } |
||
| 110 | |||
| 111 | parent::triggerWebSocketEvent($event, $params); |
||
| 112 | |||
| 113 | switch ($event) { |
||
| 114 | case 'onHandShake': |
||
| 115 | if (isset($params[1]->header['Sec-Websocket-Accept'])) { |
||
| 116 | // Successful handshake |
||
| 117 | parent::triggerWebSocketEvent('onOpen', [$this->swoole, $params[0]]); |
||
| 118 | } |
||
| 119 | $this->afterWebSocketOpen($params[0]); |
||
| 120 | break; |
||
| 121 | case 'onOpen': |
||
| 122 | $this->afterWebSocketOpen($params[1]); |
||
| 123 | break; |
||
| 124 | } |
||
| 125 | } |
||
| 126 | |||
| 127 | protected function triggerPortEvent(Port $port, $handlerClass, $event, array $params) |
||
| 128 | { |
||
| 129 | switch ($event) { |
||
| 130 | case 'onHandShake': |
||
| 131 | $this->beforeWebSocketHandShake($params[0]); |
||
| 132 | case 'onRequest': |
||
| 133 | if (!empty($this->conf['server'])) { |
||
| 134 | $params[1]->header('Server', $this->conf['server']); |
||
| 135 | } |
||
| 136 | break; |
||
| 137 | } |
||
| 138 | |||
| 139 | parent::triggerPortEvent($port, $handlerClass, $event, $params); |
||
| 140 | |||
| 141 | switch ($event) { |
||
| 142 | case 'onHandShake': |
||
| 143 | if (isset($params[1]->header['Sec-Websocket-Accept'])) { |
||
| 144 | // Successful handshake |
||
| 145 | parent::triggerPortEvent($port, $handlerClass, 'onOpen', [$this->swoole, $params[0]]); |
||
| 146 | } |
||
| 147 | $this->afterWebSocketOpen($params[0]); |
||
| 148 | break; |
||
| 149 | case 'onOpen': |
||
| 150 | $this->afterWebSocketOpen($params[1]); |
||
| 151 | break; |
||
| 152 | } |
||
| 153 | } |
||
| 154 | |||
| 155 | public function onShutdown(HttpServer $server) |
||
| 156 | { |
||
| 157 | parent::onShutdown($server); |
||
| 158 | |||
| 159 | // Fire ServerStop event |
||
| 160 | if (isset($this->conf['event_handlers']['ServerStop'])) { |
||
| 161 | $this->laravel = $this->initLaravel($this->laravelConf, $this->swoole); |
||
| 162 | $this->fireEvent('ServerStop', ServerStopInterface::class, [$server]); |
||
| 163 | } |
||
| 164 | } |
||
| 165 | |||
| 166 | public function onWorkerStart(HttpServer $server, $workerId) |
||
| 177 | } |
||
| 178 | |||
| 179 | public function onWorkerStop(HttpServer $server, $workerId) |
||
| 180 | { |
||
| 181 | parent::onWorkerStop($server, $workerId); |
||
| 182 | |||
| 183 | // Fire WorkerStop event |
||
| 184 | $this->fireEvent('WorkerStop', WorkerStopInterface::class, func_get_args()); |
||
| 185 | } |
||
| 186 | |||
| 187 | public function onWorkerError(HttpServer $server, $workerId, $workerPId, $exitCode, $signal) |
||
| 188 | { |
||
| 189 | parent::onWorkerError($server, $workerId, $workerPId, $exitCode, $signal); |
||
| 190 | |||
| 191 | Laravel::autoload($this->laravelConf['root_path']); |
||
| 192 | |||
| 193 | // Fire WorkerError event |
||
| 194 | $this->fireEvent('WorkerError', WorkerErrorInterface::class, func_get_args()); |
||
| 195 | } |
||
| 196 | |||
| 197 | protected function convertRequest(Laravel $laravel, SwooleRequest $request) |
||
| 198 | { |
||
| 199 | $rawGlobals = $laravel->getRawGlobals(); |
||
| 200 | return (new Request($request))->toIlluminateRequest($rawGlobals['_SERVER'], $rawGlobals['_ENV']); |
||
| 201 | } |
||
| 202 | |||
| 203 | public function onRequest(SwooleRequest $swooleRequest, SwooleResponse $swooleResponse) |
||
| 204 | { |
||
| 205 | try { |
||
| 206 | $laravelRequest = $this->convertRequest($this->laravel, $swooleRequest); |
||
| 207 | $this->laravel->bindRequest($laravelRequest); |
||
| 208 | $this->laravel->fireEvent('laravels.received_request', [$laravelRequest]); |
||
| 209 | $handleStaticSuccess = false; |
||
| 210 | if ($this->conf['handle_static']) { |
||
| 211 | // For Swoole < 1.9.17 |
||
| 212 | $handleStaticSuccess = $this->handleStaticResource($this->laravel, $laravelRequest, $swooleResponse); |
||
| 213 | } |
||
| 214 | if (!$handleStaticSuccess) { |
||
| 215 | $this->handleDynamicResource($this->laravel, $laravelRequest, $swooleResponse); |
||
| 216 | } |
||
| 217 | } catch (\Exception $e) { |
||
| 218 | $this->handleException($e, $swooleResponse); |
||
| 219 | } |
||
| 220 | } |
||
| 221 | |||
| 222 | /** |
||
| 223 | * @param \Exception $e |
||
| 224 | * @param SwooleResponse $response |
||
| 225 | */ |
||
| 226 | protected function handleException($e, SwooleResponse $response) |
||
| 227 | { |
||
| 228 | $error = sprintf( |
||
| 229 | 'onRequest: Uncaught exception "%s"([%d]%s) at %s:%s, %s%s', |
||
| 230 | get_class($e), |
||
| 231 | $e->getCode(), |
||
| 232 | $e->getMessage(), |
||
| 233 | $e->getFile(), |
||
| 234 | $e->getLine(), |
||
| 235 | PHP_EOL, |
||
| 236 | $e->getTraceAsString() |
||
| 237 | ); |
||
| 238 | $this->error($error); |
||
| 239 | try { |
||
| 240 | $response->status(500); |
||
| 241 | $response->end('Oops! An unexpected error occurred'); |
||
| 242 | } catch (\Exception $e) { |
||
| 243 | $this->logException($e); |
||
| 244 | } |
||
| 245 | } |
||
| 246 | |||
| 247 | protected function handleStaticResource(Laravel $laravel, IlluminateRequest $laravelRequest, SwooleResponse $swooleResponse) |
||
| 261 | } |
||
| 262 | |||
| 263 | protected function handleDynamicResource(Laravel $laravel, IlluminateRequest $laravelRequest, SwooleResponse $swooleResponse) |
||
| 280 | } |
||
| 281 | |||
| 282 | /**@var OutputStyle */ |
||
| 283 | protected static $outputStyle; |
||
| 284 | |||
| 285 | public static function setOutputStyle(OutputStyle $outputStyle) |
||
| 286 | { |
||
| 287 | static::$outputStyle = $outputStyle; |
||
| 288 | } |
||
| 289 | |||
| 290 | public static function getOutputStyle() |
||
| 293 | } |
||
| 294 | } |
||
| 295 |