From 69282bdbab0bad66b2cfdaf416bd18170e913466 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Fri, 7 Sep 2018 21:13:30 +0800 Subject: [PATCH 001/161] improve isWebsocketPushPacket function --- src/Concerns/InteractsWithWebsocket.php | 17 +++++++++++++++ src/Server/Manager.php | 8 ++----- tests/Server/ManagerTest.php | 28 +++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/Concerns/InteractsWithWebsocket.php b/src/Concerns/InteractsWithWebsocket.php index c22e1cfc..8f511e90 100644 --- a/src/Concerns/InteractsWithWebsocket.php +++ b/src/Concerns/InteractsWithWebsocket.php @@ -135,6 +135,23 @@ public function onClose($server, $fd, $reactorId) } } + /** + * Indicates if a packet is websocket push action. + * + * @param mixed + */ + protected function isWebsocketPushPacket($packet) + { + if ( !is_array($packet)) { + return false; + } + + return $this->isWebsocket + && array_key_exists('action', $packet) + && $packet['action'] === Websocket::PUSH_ACTION; + } + + /** * Push websocket message to clients. * diff --git a/src/Server/Manager.php b/src/Server/Manager.php index b5715d81..a5dc72be 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -230,12 +230,8 @@ public function onTask($server, $taskId, $srcWorkerId, $data) try { // push websocket message - if (is_array($data)) { - if ($this->isWebsocket - && array_key_exists('action', $data) - && $data['action'] === Websocket::PUSH_ACTION) { - $this->pushMessage($server, $data['data'] ?? []); - } + if ($this->isWebsocketPushPacket($data)) { + $this->pushMessage($server, $data['data'] ?? []); // push async task to queue } elseif (is_string($data)) { $decoded = json_decode($data, true); diff --git a/tests/Server/ManagerTest.php b/tests/Server/ManagerTest.php index d0b80fc7..2f81fcff 100644 --- a/tests/Server/ManagerTest.php +++ b/tests/Server/ManagerTest.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http\Tests\Server; +use Exception; use Mockery as m; use Swoole\Table; use Swoole\Http\Request; @@ -574,6 +575,9 @@ protected function getContainer($server = null, $config = null) $container->singleton('swoole.server', function () use ($server) { return $server; }); + $container->singleton(ExceptionHandler::class, function () { + return new DummyExceptionHandler; + }); return $container; } @@ -623,3 +627,27 @@ protected function mockMethod($name, \Closure $function, $namespace = null) parent::mockMethod($name, $function, 'SwooleTW\Http\Server'); } } + +class DummyExceptionHandler implements ExceptionHandler { + public function report(Exception $e) + { + $this->dump($e); + } + + public function render($request, Exception $e) + { + $this->dump($e); + } + + public function renderForConsole($output, Exception $e) + { + $this->dump($e); + } + + protected function dump($e) + { + echo "\n Server Error: "; + echo $e->getMessage(); + die; + } +} From 1b420e271b088af4b4b7e905c701903d9ebacdab Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Fri, 7 Sep 2018 22:02:05 +0800 Subject: [PATCH 002/161] improve isSwooleQueuePacket function --- src/Concerns/InteractsWithSwooleQueue.php | 25 +++++++++++++++++++++++ src/Server/Manager.php | 10 ++++----- 2 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 src/Concerns/InteractsWithSwooleQueue.php diff --git a/src/Concerns/InteractsWithSwooleQueue.php b/src/Concerns/InteractsWithSwooleQueue.php new file mode 100644 index 00000000..efed9c26 --- /dev/null +++ b/src/Concerns/InteractsWithSwooleQueue.php @@ -0,0 +1,25 @@ +isWebsocketPushPacket($data)) { $this->pushMessage($server, $data['data'] ?? []); // push async task to queue - } elseif (is_string($data)) { - $decoded = json_decode($data, true); - - if (JSON_ERROR_NONE === json_last_error() && isset($decoded['job'])) { - (new SwooleTaskJob($this->container, $server, $data, $taskId, $srcWorkerId))->fire(); - } + } elseif ($this->isSwooleQueuePacket($data)) { + (new SwooleTaskJob($this->container, $server, $data, $taskId, $srcWorkerId))->fire(); } } catch (Throwable $e) { $this->logServerError($e); From 16f83285158d5afb02e2df3231f3aa3369d662bf Mon Sep 17 00:00:00 2001 From: Zachary He Date: Fri, 21 Sep 2018 15:39:47 +1000 Subject: [PATCH 003/161] Add chunk to response content. Idea form https://blog.csdn.net/weixin_42900065/article/details/81910081. Since, latest swoole supports gzip by server param: https://wiki.swoole.com/wiki/page/973.html. So, only added chunk. --- src/Transformers/Response.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Transformers/Response.php b/src/Transformers/Response.php index 5efd0239..c4235f6a 100644 --- a/src/Transformers/Response.php +++ b/src/Transformers/Response.php @@ -110,10 +110,23 @@ protected function sendContent() } elseif ($illuminateResponse instanceof BinaryFileResponse) { $this->swooleResponse->sendfile($illuminateResponse->getFile()->getPathname()); } else { - $this->swooleResponse->end($illuminateResponse->getContent()); + $this->sendInChunk($illuminateResponse->getContent()); } } + /** + * Send content in chunk + * + * @param string $content + */ + protected function sendInChunk($content) + { + foreach (str_split($content, 1024) as $v) { + $this->swooleResponse->write($v); + } + $this->swooleResponse->end(); + } + /** * @param \Swoole\Http\Response $swooleResponse * @return \SwooleTW\Http\Server\Response From f3cb2f9fbff7830d3c4a17b14bc4eae79e96f639 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 28 Oct 2018 22:01:32 +0800 Subject: [PATCH 004/161] transform throwable to fatal exception --- src/Server/Manager.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Server/Manager.php b/src/Server/Manager.php index b5715d81..6c5fe760 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http\Server; +use Exception; use Throwable; use Swoole\Http\Server; use SwooleTW\Http\Server\Sandbox; @@ -15,6 +16,7 @@ use Illuminate\Contracts\Debug\ExceptionHandler; use SwooleTW\Http\Concerns\InteractsWithWebsocket; use SwooleTW\Http\Concerns\InteractsWithSwooleTable; +use Symfony\Component\Debug\Exception\FatalThrowableError; class Manager { @@ -385,6 +387,10 @@ protected function isInTesting() */ public function logServerError(Throwable $e) { + if (! $e instanceof Exception) { + $e = new FatalThrowableError($e); + } + $this->container[ExceptionHandler::class]->report($e); } } From e7a1193ff4d306dbf3ef9bfcbc53059e6761d009 Mon Sep 17 00:00:00 2001 From: zhangzhikun Date: Tue, 20 Nov 2018 18:19:01 +0800 Subject: [PATCH 005/161] support co::mysql --- src/Coroutine/Connectors/MySqlConnector.php | 16 +++++++++++++ src/Coroutine/PDO.php | 2 +- src/Coroutine/PDOStatement.php | 7 ++++++ src/HttpServiceProvider.php | 25 ++++++++++++++++++--- src/Server/Manager.php | 5 ++++- 5 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/Coroutine/Connectors/MySqlConnector.php b/src/Coroutine/Connectors/MySqlConnector.php index 627aadd8..10f64ba1 100644 --- a/src/Coroutine/Connectors/MySqlConnector.php +++ b/src/Coroutine/Connectors/MySqlConnector.php @@ -20,6 +20,7 @@ class MySqlConnector extends BaseConnector */ protected function createPdoConnection($dsn, $username, $password, $options) { + //TODO I'm thinking make it out by MysqlPool return new SwoolePDO($dsn, $username, $password, $options); } @@ -44,4 +45,19 @@ protected function tryAgainIfCausedByLostConnection(Exception $e, $dsn, $usernam throw $e; } + + /** + * @param $connection + * @param array $config + * if database set timezone, the laravel/lumen frame will exec + * $connection->prepare('set time_zone="'.$config['timezone'].'"')->execute(); + * this will occur to ERROR in "Coroutine\MySQL", Maybe swoole co::mysql's 'execute()' params + * mustn't be empty array. My lumen is v5.5.2 + */ + protected function configureTimezone($connection, array $config) + { + if (isset($config['timezone'])) { + $connection->prepare('set time_zone=?')->execute([$config['timezone']]); + } + } } diff --git a/src/Coroutine/PDO.php b/src/Coroutine/PDO.php index 5e4a7aeb..39fc0d3f 100644 --- a/src/Coroutine/PDO.php +++ b/src/Coroutine/PDO.php @@ -126,7 +126,7 @@ public function rollBack() public function commit() { $this->client->commit(); - $this->inTransaction = true; + $this->inTransaction = false;//TODO I think it's sample to rollback, please confirm it } public function inTransaction() diff --git a/src/Coroutine/PDOStatement.php b/src/Coroutine/PDOStatement.php index bec3fa1a..b979073a 100644 --- a/src/Coroutine/PDOStatement.php +++ b/src/Coroutine/PDOStatement.php @@ -105,6 +105,13 @@ public function execute($inputParameters = null) $this->resultSet = ($ok = $result !== false) ? $result : []; $this->afterExecute(); + //if not, the DB::connection('mysql-coroutine')->transaction(func,times) won't be work well, + //and if one sql occur error, others will be execute success, it doesn't rollback, + //also please confirm it, Thank you + if($result === false){ + throw new \PDOException($this->errorInfo(), $this->errorCode()); + } + return $ok; } diff --git a/src/HttpServiceProvider.php b/src/HttpServiceProvider.php index 6f6c0b2a..9c536798 100644 --- a/src/HttpServiceProvider.php +++ b/src/HttpServiceProvider.php @@ -156,23 +156,42 @@ protected function registerServer() /** * Register database driver for coroutine mysql. + * + * I use resolving extend db connector, but it won't be success when i use DB::connection('mysql-coroutine') + * or Model::on('mysql-coroutine'), So I change it by extend, And also make it support separate read and write + * when using DB::connection('mysql-coroutine::write') or DB::connection('mysql-coroutine')->useWritePdo() */ protected function registerDatabaseDriver() { - $this->app->resolving('db', function ($db) { + $this->app->extend('db', function ($db) { $db->extend('mysql-coroutine', function ($config, $name) { $config['name'] = $name; + + if (isset($config['read'])) { + $config = array_merge($config, $config['read']); + } + + $connectionRead = function () use ($config) { + return (new MySqlConnector())->connect($config); + }; + + if (isset($config['write'])) { + $config = array_merge($config, $config['write']); + } + $connection = function () use ($config) { return (new MySqlConnector())->connect($config); }; - return new MySqlConnection( + return (new MySqlConnection( $connection, $config['database'], $config['prefix'], $config - ); + ))->setReadPdo($connectionRead); }); + + return $db; }); } diff --git a/src/Server/Manager.php b/src/Server/Manager.php index b5715d81..2f4f682b 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -140,14 +140,15 @@ public function onManagerStart() public function onWorkerStart($server) { $this->clearCache(); - $this->setProcessName('worker process'); $this->container['events']->fire('swoole.workerStart', func_get_args()); // don't init laravel app in task workers if ($server->taskworker) { + $this->setProcessName('task process');//mark task process return; } + $this->setProcessName('worker process'); // clear events instance in case of repeated listeners in worker process Facade::clearResolvedInstance('events'); @@ -244,6 +245,7 @@ public function onTask($server, $taskId, $srcWorkerId, $data) (new SwooleTaskJob($this->container, $server, $data, $taskId, $srcWorkerId))->fire(); } } + $server->finish("$taskId finished");//if not ,don't call onFinish } catch (Throwable $e) { $this->logServerError($e); } @@ -255,6 +257,7 @@ public function onTask($server, $taskId, $srcWorkerId, $data) public function onFinish($server, $taskId, $data) { // task worker callback + $this->container['events']->fire('swoole.finish', func_get_args()); return; } From 24d1a316d8f086332bf910cfa288a8bb596d1edc Mon Sep 17 00:00:00 2001 From: zhangzhikun Date: Wed, 21 Nov 2018 11:51:44 +0800 Subject: [PATCH 006/161] update : --- src/Coroutine/PDO.php | 2 +- src/Coroutine/PDOStatement.php | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Coroutine/PDO.php b/src/Coroutine/PDO.php index 39fc0d3f..ccaac281 100644 --- a/src/Coroutine/PDO.php +++ b/src/Coroutine/PDO.php @@ -184,7 +184,7 @@ public function prepare($statement, $driverOptions = null) $i = 0; $bindKeyMap = []; $statement = preg_replace_callback( - '/:(\w+)\b/', + '/:([a-zA-Z_]\w*?)\b/', function ($matches) use (&$i, &$bindKeyMap) { $bindKeyMap[$matches[1]] = $i++; diff --git a/src/Coroutine/PDOStatement.php b/src/Coroutine/PDOStatement.php index b979073a..13ea4d84 100644 --- a/src/Coroutine/PDOStatement.php +++ b/src/Coroutine/PDOStatement.php @@ -95,7 +95,9 @@ public function execute($inputParameters = null) $inputParameters = []; if (! empty($this->statement->bindKeyMap)) { foreach ($this->statement->bindKeyMap as $nameKey => $numKey) { - $inputParameters[$numKey] = $this->bindMap[$nameKey]; + if (isset($this->bindMap[$nameKey])) { + $inputParameters[$numKey] = $this->bindMap[$nameKey]; + } } } else { $inputParameters = $this->bindMap; From cc436f132e4995bc018e375ff7e7d6ce3fa11ec7 Mon Sep 17 00:00:00 2001 From: zhangzhikun Date: Wed, 21 Nov 2018 11:52:55 +0800 Subject: [PATCH 007/161] rm configureTimezone --- src/Coroutine/Connectors/MySqlConnector.php | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/Coroutine/Connectors/MySqlConnector.php b/src/Coroutine/Connectors/MySqlConnector.php index 10f64ba1..86b6a0f2 100644 --- a/src/Coroutine/Connectors/MySqlConnector.php +++ b/src/Coroutine/Connectors/MySqlConnector.php @@ -45,19 +45,4 @@ protected function tryAgainIfCausedByLostConnection(Exception $e, $dsn, $usernam throw $e; } - - /** - * @param $connection - * @param array $config - * if database set timezone, the laravel/lumen frame will exec - * $connection->prepare('set time_zone="'.$config['timezone'].'"')->execute(); - * this will occur to ERROR in "Coroutine\MySQL", Maybe swoole co::mysql's 'execute()' params - * mustn't be empty array. My lumen is v5.5.2 - */ - protected function configureTimezone($connection, array $config) - { - if (isset($config['timezone'])) { - $connection->prepare('set time_zone=?')->execute([$config['timezone']]); - } - } } From 20b622a9b49e072bd224f0eb6dfaabf3dd6737e8 Mon Sep 17 00:00:00 2001 From: zhangzhikun Date: Wed, 21 Nov 2018 15:08:20 +0800 Subject: [PATCH 008/161] add co::mysql test --- src/Task/SwooleTaskQueue.php | 3 ++- tests/Coroutine/MysqlTest.php | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 tests/Coroutine/MysqlTest.php diff --git a/src/Task/SwooleTaskQueue.php b/src/Task/SwooleTaskQueue.php index 734fbc4a..2cb76603 100644 --- a/src/Task/SwooleTaskQueue.php +++ b/src/Task/SwooleTaskQueue.php @@ -49,7 +49,8 @@ public function push($job, $data = '', $queue = null) */ public function pushRaw($payload, $queue = null, array $options = []) { - return $this->swoole->task($payload, ! is_numeric($queue) ? 1 : (int) $queue); + //wiki https://wiki.swoole.com/wiki/page/134.html, task($data,$dst_worker_id), $dst_worker_id should be default -1 + return $this->swoole->task($payload, (!is_numeric($queue) || $queue < 0) ? -1 : (int)$queue); } /** diff --git a/tests/Coroutine/MysqlTest.php b/tests/Coroutine/MysqlTest.php new file mode 100644 index 00000000..30890615 --- /dev/null +++ b/tests/Coroutine/MysqlTest.php @@ -0,0 +1,34 @@ +where('id', 32)->get(['order_num', 'cuser_name']); +// CashOrder::on('mysql-coroutine')->where('id',32)->update(['cuser_name'=>'Linda']); +// $ret=CashOrder::on('mysql-coroutine')->where('id',32)->get(['order_num','cuser_name'])->toArray(); +// $ret=CashOrder::on('mysql-coroutine')->insertGetId(['order_num'=>'xxx0011','cuser_name'=>'myname']); +// $ret=CashOrder::on('mysql-coroutine')->where('id',32)->get(['order_num','cuser_name'])->toArray(); + $ret = DB::connection('mysql-coroutine::write')->table('cash_order')->where('id', 32)->get(['order_num', 'cuser_name']); + $ret = DB::connection('mysql-coroutine')->select("SELECT sleep(1)"); +// $id=CashUser::on('mysql-coroutine')->insertGetId(['cid'=>78,'name'=>'ddd']); + + $id = 0; + try { + // I set cash_user table column `cid` for UNIQUE INDEX to test transaction err; + DB::connection('mysql-coroutine')->transaction(function () use (&$id) { + CashOrder::on('mysql-coroutine')->whereKey(45)->update(['order_num' => 'abcdef1111', 'cuser_name' => 'zzk']); + $id = CashUser::on('mysql-coroutine')->insertGetId(['cid' => 89, 'name' => 'hello']); + }); + } catch (\Exception $e) { + $err = $e->getMessage(); + return compact('id', 'ret', 'err'); + } + return compact('id', 'ret'); + } +} \ No newline at end of file From 973a0f3db4e7b97f4a6de009a4b472d7ba231632 Mon Sep 17 00:00:00 2001 From: zhangzhikun Date: Wed, 21 Nov 2018 15:13:04 +0800 Subject: [PATCH 009/161] up --- tests/Coroutine/MysqlTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Coroutine/MysqlTest.php b/tests/Coroutine/MysqlTest.php index 30890615..4fa73b36 100644 --- a/tests/Coroutine/MysqlTest.php +++ b/tests/Coroutine/MysqlTest.php @@ -31,4 +31,4 @@ public function testQuery() } return compact('id', 'ret'); } -} \ No newline at end of file +} From 6a1fae7e20273ebe25b8150febe38637747faa2f Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Thu, 13 Dec 2018 15:06:47 +0800 Subject: [PATCH 010/161] confirm PR 165: fix mysql transaction and task default param --- src/Coroutine/PDO.php | 2 +- src/Coroutine/PDOStatement.php | 5 +--- src/HttpServiceProvider.php | 53 +++++++++++++++++++--------------- src/Server/Manager.php | 3 +- tests/Coroutine/MysqlTest.php | 34 ---------------------- 5 files changed, 32 insertions(+), 65 deletions(-) delete mode 100644 tests/Coroutine/MysqlTest.php diff --git a/src/Coroutine/PDO.php b/src/Coroutine/PDO.php index ccaac281..60415958 100644 --- a/src/Coroutine/PDO.php +++ b/src/Coroutine/PDO.php @@ -126,7 +126,7 @@ public function rollBack() public function commit() { $this->client->commit(); - $this->inTransaction = false;//TODO I think it's sample to rollback, please confirm it + $this->inTransaction = true; } public function inTransaction() diff --git a/src/Coroutine/PDOStatement.php b/src/Coroutine/PDOStatement.php index 13ea4d84..8b54dbc6 100644 --- a/src/Coroutine/PDOStatement.php +++ b/src/Coroutine/PDOStatement.php @@ -107,10 +107,7 @@ public function execute($inputParameters = null) $this->resultSet = ($ok = $result !== false) ? $result : []; $this->afterExecute(); - //if not, the DB::connection('mysql-coroutine')->transaction(func,times) won't be work well, - //and if one sql occur error, others will be execute success, it doesn't rollback, - //also please confirm it, Thank you - if($result === false){ + if ($result === false){ throw new \PDOException($this->errorInfo(), $this->errorCode()); } diff --git a/src/HttpServiceProvider.php b/src/HttpServiceProvider.php index 9c536798..f3cc7e41 100644 --- a/src/HttpServiceProvider.php +++ b/src/HttpServiceProvider.php @@ -156,45 +156,50 @@ protected function registerServer() /** * Register database driver for coroutine mysql. - * - * I use resolving extend db connector, but it won't be success when i use DB::connection('mysql-coroutine') - * or Model::on('mysql-coroutine'), So I change it by extend, And also make it support separate read and write - * when using DB::connection('mysql-coroutine::write') or DB::connection('mysql-coroutine')->useWritePdo() */ protected function registerDatabaseDriver() { $this->app->extend('db', function ($db) { $db->extend('mysql-coroutine', function ($config, $name) { - $config['name'] = $name; - - if (isset($config['read'])) { - $config = array_merge($config, $config['read']); - } - - $connectionRead = function () use ($config) { - return (new MySqlConnector())->connect($config); - }; + $config = $this->getMergedDatabaseConfig($config, $name); - if (isset($config['write'])) { - $config = array_merge($config, $config['write']); - } - - $connection = function () use ($config) { - return (new MySqlConnector())->connect($config); - }; - - return (new MySqlConnection( - $connection, + $connection = new MySqlConnection( + $this->getNewMySqlConnection($config), $config['database'], $config['prefix'], $config - ))->setReadPdo($connectionRead); + ); + + if (isset($config['read'])) { + $connection->setReadPdo($this->getNewMySqlConnection($config)); + } + + return $connection; }); return $db; }); } + protected function getMergedDatabaseConfig(array $config, string $name) + { + $config['name'] = $name; + + if (isset($config['read'])) { + $config = array_merge($config, $config['read']); + } + if (isset($config['write'])) { + $config = array_merge($config, $config['write']); + } + + return $config; + } + + protected function getNewMySqlConnection(array $config) + { + return (new MySqlConnector())->connect($config); + } + /** * Register queue driver for swoole async task. */ diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 38171579..1fa1bf90 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -147,7 +147,7 @@ public function onWorkerStart($server) // don't init laravel app in task workers if ($server->taskworker) { - $this->setProcessName('task process');//mark task process + $this->setProcessName('task process'); return; } $this->setProcessName('worker process'); @@ -247,7 +247,6 @@ public function onTask($server, $taskId, $srcWorkerId, $data) (new SwooleTaskJob($this->container, $server, $data, $taskId, $srcWorkerId))->fire(); } } - $server->finish("$taskId finished");//if not ,don't call onFinish } catch (Throwable $e) { $this->logServerError($e); } diff --git a/tests/Coroutine/MysqlTest.php b/tests/Coroutine/MysqlTest.php deleted file mode 100644 index 4fa73b36..00000000 --- a/tests/Coroutine/MysqlTest.php +++ /dev/null @@ -1,34 +0,0 @@ -where('id', 32)->get(['order_num', 'cuser_name']); -// CashOrder::on('mysql-coroutine')->where('id',32)->update(['cuser_name'=>'Linda']); -// $ret=CashOrder::on('mysql-coroutine')->where('id',32)->get(['order_num','cuser_name'])->toArray(); -// $ret=CashOrder::on('mysql-coroutine')->insertGetId(['order_num'=>'xxx0011','cuser_name'=>'myname']); -// $ret=CashOrder::on('mysql-coroutine')->where('id',32)->get(['order_num','cuser_name'])->toArray(); - $ret = DB::connection('mysql-coroutine::write')->table('cash_order')->where('id', 32)->get(['order_num', 'cuser_name']); - $ret = DB::connection('mysql-coroutine')->select("SELECT sleep(1)"); -// $id=CashUser::on('mysql-coroutine')->insertGetId(['cid'=>78,'name'=>'ddd']); - - $id = 0; - try { - // I set cash_user table column `cid` for UNIQUE INDEX to test transaction err; - DB::connection('mysql-coroutine')->transaction(function () use (&$id) { - CashOrder::on('mysql-coroutine')->whereKey(45)->update(['order_num' => 'abcdef1111', 'cuser_name' => 'zzk']); - $id = CashUser::on('mysql-coroutine')->insertGetId(['cid' => 89, 'name' => 'hello']); - }); - } catch (\Exception $e) { - $err = $e->getMessage(); - return compact('id', 'ret', 'err'); - } - return compact('id', 'ret'); - } -} From b8cea6299ed74e6b9051a8c35c5d38b7cb41f669 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Thu, 13 Dec 2018 15:30:00 +0800 Subject: [PATCH 011/161] fix some wording --- src/Coroutine/Context.php | 4 ++-- src/Server/Sandbox.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Coroutine/Context.php b/src/Coroutine/Context.php index a2f49a34..0e962f7f 100644 --- a/src/Coroutine/Context.php +++ b/src/Coroutine/Context.php @@ -62,7 +62,7 @@ public static function removeData(string $key) } /** - * Get data by current coroutine id. + * Get data keys by current coroutine id. */ public static function getDataKeys() { @@ -70,7 +70,7 @@ public static function getDataKeys() } /** - * Get data by current coroutine id. + * Clear data by current coroutine id. */ public static function clear() { diff --git a/src/Server/Sandbox.php b/src/Server/Sandbox.php index 0dbf367f..cc3d1c8d 100644 --- a/src/Server/Sandbox.php +++ b/src/Server/Sandbox.php @@ -326,7 +326,7 @@ public function getSnapshot() /** * Remove current request. */ - protected function removeRequest() + public function removeRequest() { return Context::removeData('_request'); } From b996e364525fc9ff70a5db4d5ff00876e189b8fc Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Thu, 13 Dec 2018 16:24:19 +0800 Subject: [PATCH 012/161] fix exception handler binding for manager test --- src/HttpServiceProvider.php | 6 ++++++ tests/Server/ManagerTest.php | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/HttpServiceProvider.php b/src/HttpServiceProvider.php index f3cc7e41..e74d7199 100644 --- a/src/HttpServiceProvider.php +++ b/src/HttpServiceProvider.php @@ -181,6 +181,9 @@ protected function registerDatabaseDriver() }); } + /** + * Get mereged config for coroutine mysql. + */ protected function getMergedDatabaseConfig(array $config, string $name) { $config['name'] = $name; @@ -195,6 +198,9 @@ protected function getMergedDatabaseConfig(array $config, string $name) return $config; } + /** + * Get a new mysql connection. + */ protected function getNewMySqlConnection(array $config) { return (new MySqlConnector())->connect($config); diff --git a/tests/Server/ManagerTest.php b/tests/Server/ManagerTest.php index d0b80fc7..c70c89f2 100644 --- a/tests/Server/ManagerTest.php +++ b/tests/Server/ManagerTest.php @@ -12,6 +12,7 @@ use Illuminate\Container\Container; use SwooleTW\Http\Websocket\Parser; use SwooleTW\Http\Table\SwooleTable; +use Laravel\Lumen\Exceptions\Handler; use Swoole\Http\Server as HttpServer; use Illuminate\Support\Facades\Config; use SwooleTW\Http\Websocket\Websocket; @@ -574,6 +575,7 @@ protected function getContainer($server = null, $config = null) $container->singleton('swoole.server', function () use ($server) { return $server; }); + $container->singleton(ExceptionHandler::class, Handler::class); return $container; } From 781773d2703c9a0619fac360e81695783483c1dd Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Thu, 13 Dec 2018 18:28:53 +0800 Subject: [PATCH 013/161] add some tests for sandbox --- src/Server/Sandbox.php | 8 -------- tests/Server/SandboxTest.php | 25 +++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/Server/Sandbox.php b/src/Server/Sandbox.php index cc3d1c8d..1ab2041b 100644 --- a/src/Server/Sandbox.php +++ b/src/Server/Sandbox.php @@ -323,14 +323,6 @@ public function getSnapshot() return Context::getApp(); } - /** - * Remove current request. - */ - public function removeRequest() - { - return Context::removeData('_request'); - } - /** * Get current request. */ diff --git a/tests/Server/SandboxTest.php b/tests/Server/SandboxTest.php index 9f04a1e6..56414f9f 100644 --- a/tests/Server/SandboxTest.php +++ b/tests/Server/SandboxTest.php @@ -99,6 +99,31 @@ public function testGetApplication() $this->assertTrue($sandbox->getSnapshot() instanceof Container); } + public function testGetCachedSnapshot() + { + $container = m::mock(Container::class); + $snapshot = m::mock(Container::class); + $snapshot->shouldReceive('offsetGet') + ->with('foo') + ->once() + ->andReturn($result = 'bar'); + + $sandbox = new Sandbox; + $sandbox->setBaseApp($container); + $sandbox->setSnapshot($snapshot); + + $this->assertTrue($sandbox->getApplication() instanceof Container); + $this->assertEquals($result, $sandbox->getApplication()->foo); + } + + public function testRunWithoutSnapshot() + { + $this->expectException(SandboxException::class); + + $sandbox = new Sandbox; + $sandbox->run($request = m::mock(Request::class)); + } + public function testSetRequest() { $request = m::mock(Request::class); From 5d8ee95964f5668cd1a1288d413085cc0f078ab4 Mon Sep 17 00:00:00 2001 From: Fractal Zombie Date: Wed, 19 Dec 2018 21:11:55 +0200 Subject: [PATCH 014/161] Refactoring. Removes old laravel|lumen versions. Added support for 5.6|5.7 laravel|lumen. Added to config support for hot reload (Next PR). --- .gitignore | 1 + .scrutinizer.yml | 12 + .travis.yml | 12 +- README.md | 2 +- composer.json | 124 ++++----- config/swoole_http.php | 19 +- config/swoole_websocket.php | 4 +- copy_versioned_files.php | 27 ++ phpunit.xml.dist | 10 +- routes/laravel_routes.php | 1 + routes/lumen_routes.php | 4 +- routes/websocket.php | 3 +- src/Commands/HttpServerCommand.php | 114 ++++----- src/Concerns/InteractsWithSwooleTable.php | 29 ++- src/Concerns/InteractsWithWebsocket.php | 238 +++++++++++------- src/Concerns/ResetApplication.php | 9 +- src/Concerns/WithApplication.php | 43 ++-- src/Controllers/SocketIOController.php | 11 +- src/Coroutine/ConnectionException.php | 1 + src/Coroutine/Connectors/ConnectorFactory.php | 106 ++++++++ src/Coroutine/Connectors/MySqlConnector.php | 34 +-- src/Coroutine/Context.php | 18 +- src/Coroutine/MySqlConnection.php | 14 +- src/Coroutine/PDO.php | 159 +++++++++--- src/Coroutine/PDOStatement.php | 101 +++++--- src/Coroutine/StatementException.php | 1 + .../FrameworkNotSupportException.php | 22 ++ src/Exceptions/SandboxException.php | 1 + .../WebsocketNotSetInConfigException.php | 22 ++ src/Helpers/FW.php | 103 ++++++++ src/Helpers/OS.php | 55 ++++ src/Helpers/Service.php | 17 ++ src/HttpServiceProvider.php | 91 +++++-- src/LaravelServiceProvider.php | 3 +- src/LumenServiceProvider.php | 1 + src/Server/Facades/Sandbox.php | 1 + src/Server/Facades/Server.php | 1 + src/Server/Manager.php | 139 +++++----- src/Server/Resetters/BindRequest.php | 9 +- src/Server/Resetters/ClearInstances.php | 6 +- .../Resetters/RebindKernelContainer.php | 13 +- .../Resetters/RebindRouterContainer.php | 17 +- src/Server/Resetters/RebindViewContainer.php | 16 +- src/Server/Resetters/ResetConfig.php | 6 +- src/Server/Resetters/ResetCookie.php | 6 +- src/Server/Resetters/ResetProviders.php | 14 +- src/Server/Resetters/ResetSession.php | 6 +- src/Server/Resetters/ResetterContract.php | 3 +- src/Server/Sandbox.php | 81 ++++-- src/Server/helpers.php | 12 +- src/Table/Facades/SwooleTable.php | 4 + src/Table/SwooleTable.php | 6 +- src/Task/Connectors/SwooleTaskConnector.php | 15 +- src/Task/QueueFactory.php | 108 ++++++++ src/Task/SwooleTaskJob.php | 30 ++- src/Task/SwooleTaskQueue.php | 50 ++-- src/Transformers/Request.php | 34 ++- src/Transformers/Response.php | 23 +- src/Websocket/Authenticatable.php | 43 +++- src/Websocket/Facades/Room.php | 4 + src/Websocket/Facades/Websocket.php | 4 + src/Websocket/HandlerContract.php | 1 + src/Websocket/Middleware/Authenticate.php | 15 +- src/Websocket/Middleware/DecryptCookies.php | 47 ++-- src/Websocket/Middleware/StartSession.php | 26 +- src/Websocket/Parser.php | 8 +- src/Websocket/Push.php | 205 +++++++++++++++ src/Websocket/Rooms/RedisRoom.php | 160 +++++++++--- src/Websocket/Rooms/RoomContract.php | 35 ++- src/Websocket/Rooms/TableRoom.php | 121 +++++++-- src/Websocket/SimpleParser.php | 8 +- src/Websocket/SocketIO/Packet.php | 27 +- src/Websocket/SocketIO/SocketIOParser.php | 11 +- .../SocketIO/Strategies/HeartbeatStrategy.php | 4 + src/Websocket/SocketIO/WebsocketHandler.php | 10 +- src/Websocket/Websocket.php | 63 +++-- stubs/5.5/MySqlConnector.stub | 53 ++++ stubs/5.6/MySqlConnector.stub | 53 ++++ stubs/5.6/SwooleTaskQueue.stub | 114 +++++++++ stubs/5.7/SwooleTaskQueue.stub | 115 +++++++++ tests/Coroutine/ConnectorFactoryTest.php | 45 ++++ tests/Coroutine/ContextTest.php | 7 +- tests/Server/ManagerTest.php | 77 +++--- tests/Server/ResettersTest.php | 31 ++- tests/Server/SandboxTest.php | 45 +++- tests/SocketIO/PacketTest.php | 15 +- tests/SocketIO/ParserTest.php | 11 +- tests/SocketIO/SocketIOControllerTest.php | 18 +- tests/SocketIO/WebsocketHandlerTest.php | 8 +- tests/Table/TableTest.php | 3 +- tests/Task/FakeJob.php | 5 +- tests/Task/QueueFactoryTest.php | 58 +++++ tests/Task/SwooleJobTest.php | 5 +- tests/Task/SwooleQueueTest.php | 7 +- tests/TestCase.php | 9 +- tests/Transformers/RequestTest.php | 16 +- tests/Transformers/ResponseTest.php | 5 +- .../Websocket/Middleware/AuthenticateTest.php | 5 +- .../Middleware/DecrpytCookiesTest.php | 11 +- .../Websocket/Middleware/StartSessionTest.php | 5 +- tests/Websocket/RedisRoomTest.php | 3 +- tests/Websocket/SimpleParserTest.php | 6 +- tests/Websocket/TableRoomTest.php | 3 +- tests/Websocket/WebsocketTest.php | 18 +- tests/fixtures/bootstrap/app.php | 8 +- .../app/Providers/RouteServiceProvider.php | 1 + .../app/Providers/TestServiceProvider.php | 1 + tests/fixtures/laravel/config/swoole_http.php | 2 +- .../app/providers/TestServiceProvider.php | 1 + tests/fixtures/lumen/config/swoole_http.php | 2 +- 110 files changed, 2772 insertions(+), 798 deletions(-) create mode 100644 .scrutinizer.yml create mode 100644 copy_versioned_files.php create mode 100644 src/Coroutine/Connectors/ConnectorFactory.php create mode 100644 src/Exceptions/FrameworkNotSupportException.php create mode 100644 src/Exceptions/WebsocketNotSetInConfigException.php create mode 100644 src/Helpers/FW.php create mode 100644 src/Helpers/OS.php create mode 100644 src/Helpers/Service.php create mode 100644 src/Task/QueueFactory.php create mode 100644 src/Websocket/Push.php create mode 100644 stubs/5.5/MySqlConnector.stub create mode 100644 stubs/5.6/MySqlConnector.stub create mode 100644 stubs/5.6/SwooleTaskQueue.stub create mode 100644 stubs/5.7/SwooleTaskQueue.stub create mode 100644 tests/Coroutine/ConnectorFactoryTest.php create mode 100644 tests/Task/QueueFactoryTest.php diff --git a/.gitignore b/.gitignore index 8918ec05..b56fa873 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .DS_Store phpunit.xml composer.lock +.scannerwork # Folders vendor diff --git a/.scrutinizer.yml b/.scrutinizer.yml new file mode 100644 index 00000000..90494730 --- /dev/null +++ b/.scrutinizer.yml @@ -0,0 +1,12 @@ +build: + environment: + php: 7.2 + +filter: + excluded_paths: + - "tests/*" + - "routes/*" + - "config/*" + - "stubs/*" + dependency_paths: + - "vendor/*" \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 6709f198..8b7faf44 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,10 +4,6 @@ sudo: false matrix: include: - - php: 7.2 - env: FRAMEWORK_VERSION=laravel/framework:5.1.* - - php: 7.2 - env: FRAMEWORK_VERSION=laravel/framework:5.2.* - php: 7.2 env: FRAMEWORK_VERSION=laravel/framework:5.3.* - php: 7.2 @@ -15,15 +11,19 @@ matrix: - php: 7.2 env: FRAMEWORK_VERSION=laravel/framework:5.5.* - php: 7.2 - env: FRAMEWORK_VERSION=laravel/lumen-framework:5.1.* + env: FRAMEWORK_VERSION=laravel/framework:5.6.* - php: 7.2 - env: FRAMEWORK_VERSION=laravel/lumen-framework:5.2.* + env: FRAMEWORK_VERSION=laravel/framework:5.7.* - php: 7.2 env: FRAMEWORK_VERSION=laravel/lumen-framework:5.3.* - php: 7.2 env: FRAMEWORK_VERSION=laravel/lumen-framework:5.4.* - php: 7.2 env: FRAMEWORK_VERSION=laravel/lumen-framework:5.5.* + - php: 7.2 + env: FRAMEWORK_VERSION=laravel/lumen-framework:5.6.* + - php: 7.2 + env: FRAMEWORK_VERSION=laravel/lumen-framework:5.7.* before_install: - printf "\n" | pecl install swoole diff --git a/README.md b/README.md index 5fef1611..2c9fbbc7 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This package provides a high performance HTTP server to speed up your Laravel/Lu | PHP | Laravel | Lumen | Swoole | |:-------:|:-------:|:-----:|:-------:| -| >=7.1 | ~5.1 | ~5.1 | >=4.0.0 | +| >=7.1 | ~5.3 | ~5.1 | >=4.0.0 | ## Features diff --git a/composer.json b/composer.json index 85b7537c..b45c7ab5 100644 --- a/composer.json +++ b/composer.json @@ -1,60 +1,72 @@ { - "name": "swooletw/laravel-swoole", - "description": "High performance HTTP server based on Swoole. Speed up your Laravel and Lumen applications.", - "keywords": ["swoole", "laravel", "lumen", "performance", "http", "server"], - "license": "MIT", - "authors": [ - { - "name": "Albert Chen", - "email": "albert@unisharp.com" - }, - { - "name": "Huang Yi", - "email": "coodeer@163.com" - } - ], - "require": { - "php": "^7.1", - "illuminate/console": "~5.1", - "illuminate/contracts": "~5.1", - "illuminate/http": "~5.1", - "illuminate/support": "~5.1", - "predis/predis": "^1.1" - }, - "require-dev": { - "laravel/lumen-framework": "~5.1", - "phpunit/phpunit": "^6.1", - "phpunit/php-code-coverage": "^5.2", - "satooshi/php-coveralls": "^1.0", - "mockery/mockery": "~1.0", - "codedungeon/phpunit-result-printer": "^0.14.0", - "php-mock/php-mock": "^2.0" - }, - "autoload": { - "files": [ - "src/Server/helpers.php" - ], - "psr-4": { - "SwooleTW\\Http\\": "src" - } - }, - "autoload-dev": { - "psr-4": { - "SwooleTW\\Http\\Tests\\": "tests", - "SwooleTW\\Http\\Tests\\Fixtures\\Laravel\\App\\": "tests/fixtures/laravel/app" - } + "name": "swooletw/laravel-swoole", + "description": "High performance HTTP server based on Swoole. Speed up your Laravel and Lumen applications.", + "keywords": [ + "swoole", + "laravel", + "lumen", + "performance", + "http", + "server" + ], + "license": "MIT", + "authors": [ + { + "name": "Albert Chen", + "email": "albert@unisharp.com" }, - "extra": { - "laravel": { - "providers": [ - "SwooleTW\\Http\\LaravelServiceProvider" - ], - "aliases": { - "Server": "SwooleTW\\Http\\Server\\Facades\\Server", - "Table": "SwooleTW\\Http\\Server\\Facades\\Table", - "Room": "SwooleTW\\Http\\Websocket\\Facades\\Room", - "Websocket": "SwooleTW\\Http\\Websocket\\Facades\\Websocket" - } - } + { + "name": "Huang Yi", + "email": "coodeer@163.com" + } + ], + "require": { + "php": "^7.2", + "illuminate/console": "~5.3", + "illuminate/contracts": "~5.3", + "illuminate/http": "~5.3", + "illuminate/support": "~5.3", + "predis/predis": "^1.1" + }, + "require-dev": { + "laravel/lumen-framework": "~5.3", + "phpunit/phpunit": "^6.1", + "phpunit/php-code-coverage": "^5.2", + "satooshi/php-coveralls": "^1.0", + "mockery/mockery": "~1.0", + "codedungeon/phpunit-result-printer": "^0.14.0", + "php-mock/php-mock": "^2.0" + }, + "autoload": { + "files": [ + "src/Server/helpers.php" + ], + "psr-4": { + "SwooleTW\\Http\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "SwooleTW\\Http\\Tests\\": "tests", + "SwooleTW\\Http\\Tests\\Fixtures\\Laravel\\App\\": "tests/fixtures/laravel/app" + } + }, + "extra": { + "laravel": { + "providers": [ + "SwooleTW\\Http\\LaravelServiceProvider" + ], + "aliases": { + "Server": "SwooleTW\\Http\\Server\\Facades\\Server", + "Table": "SwooleTW\\Http\\Server\\Facades\\Table", + "Room": "SwooleTW\\Http\\Websocket\\Facades\\Room", + "Websocket": "SwooleTW\\Http\\Websocket\\Facades\\Websocket" + } } + }, + "scripts": { + "post-autoload-dump": [ + "@php copy_versioned_files.php" + ] + } } diff --git a/config/swoole_http.php b/config/swoole_http.php index 2f70159c..a49fcb6b 100644 --- a/config/swoole_http.php +++ b/config/swoole_http.php @@ -1,7 +1,5 @@ base_path('public'), // Determine if to use swoole to respond request for static files 'handle_static_files' => env('SWOOLE_HANDLE_STATIC', true), + 'log' => env('SWOOLE_HTTP_LOG', true), // You must add --enable-openssl while compiling Swoole // Put `SWOOLE_SOCK_TCP | SWOOLE_SSL` if you want to enable SSL 'socket_type' => SWOOLE_SOCK_TCP, + 'process_type' => SWOOLE_PROCESS, 'options' => [ 'pid_file' => env('SWOOLE_HTTP_PID_FILE', base_path('storage/logs/swoole_http.pid')), 'log_file' => env('SWOOLE_HTTP_LOG_FILE', base_path('storage/logs/swoole_http.log')), @@ -53,6 +53,19 @@ 'enabled' => env('SWOOLE_HTTP_WEBSOCKET', false), ], + /* + |-------------------------------------------------------------------------- + | Hot reload configuration + |-------------------------------------------------------------------------- + */ + 'hot_reload' => [ + 'enabled' => env('SWOOLE_HOT_RELOAD_ENABLE', true), + 'level' => env('SWOOLE_HOT_RELOAD_DEEP_LEVEL', 10), + 'directory' => env('SWOOLE_HOT_RELOAD_DIRECTORY', base_path()), + 'log' => env('SWOOLE_HOT_RELOAD_LOG', true), + 'files' => ['*.php'], + ], + /* |-------------------------------------------------------------------------- | Console output will be transferred to response content if enabled. @@ -120,5 +133,5 @@ // ['name' => 'column_name', 'type' => Table::TYPE_STRING, 'size' => 1024], // ] // ], - ] + ], ]; diff --git a/config/swoole_websocket.php b/config/swoole_websocket.php index a9c770da..d01a1edb 100644 --- a/config/swoole_websocket.php +++ b/config/swoole_websocket.php @@ -77,7 +77,7 @@ 'room_rows' => 4096, 'room_size' => 2048, 'client_rows' => 8192, - 'client_size' => 2048 + 'client_size' => 2048, ], 'redis' => [ @@ -92,6 +92,6 @@ // ], 'prefix' => 'swoole:', - ] + ], ], ]; diff --git a/copy_versioned_files.php b/copy_versioned_files.php new file mode 100644 index 00000000..50d9393a --- /dev/null +++ b/copy_versioned_files.php @@ -0,0 +1,27 @@ + - - - ./tests - - ./src + + + ./tests + + diff --git a/routes/laravel_routes.php b/routes/laravel_routes.php index 9afb5f6e..53564c96 100644 --- a/routes/laravel_routes.php +++ b/routes/laravel_routes.php @@ -1,5 +1,6 @@ get('socket.io', [ - 'as' => 'io.get', 'uses' => 'SocketIOController@upgrade' + 'as' => 'io.get', 'uses' => 'SocketIOController@upgrade', ]); $app->post('socket.io', [ - 'as' => 'io.post', 'uses' => 'SocketIOController@reject' + 'as' => 'io.post', 'uses' => 'SocketIOController@reject', ]); diff --git a/routes/websocket.php b/routes/websocket.php index a956ac7d..ddebfe14 100644 --- a/routes/websocket.php +++ b/routes/websocket.php @@ -1,5 +1,6 @@ emit('message', $data); }); - -// Websocket::on('test', 'ExampleController@method'); \ No newline at end of file diff --git a/src/Commands/HttpServerCommand.php b/src/Commands/HttpServerCommand.php index 157c9b54..30ab626d 100644 --- a/src/Commands/HttpServerCommand.php +++ b/src/Commands/HttpServerCommand.php @@ -2,9 +2,11 @@ namespace SwooleTW\Http\Commands; -use Throwable; -use Swoole\Process; + use Illuminate\Console\Command; +use Illuminate\Support\Arr; +use Swoole\Process; +use Throwable; /** * @codeCoverageIgnore @@ -38,14 +40,14 @@ class HttpServerCommand extends Command * * @var int */ - protected $pid; + protected $currentPid; /** * The configs for this package. * * @var array */ - protected $configs; + protected $config; /** * Execute the console command. @@ -65,7 +67,7 @@ public function handle() */ protected function loadConfigs() { - $this->configs = $this->laravel['config']->get('swoole_http'); + $this->config = $this->laravel->make('config')->get('swoole_http'); } /** @@ -81,13 +83,14 @@ protected function runAction() */ protected function start() { - if ($this->isRunning($this->getPid())) { + if ($this->isRunning($this->getCurrentPid())) { $this->error('Failed! swoole_http_server process is already running.'); - exit(1); + + return; } - $host = $this->configs['server']['host']; - $port = $this->configs['server']['port']; + $host = Arr::get($this->config, 'server.host'); + $port = Arr::get($this->config, 'server.port'); $this->info('Starting swoole http server...'); $this->info("Swoole http server started: "); @@ -104,11 +107,12 @@ protected function start() */ protected function stop() { - $pid = $this->getPid(); + $pid = $this->getCurrentPid(); - if (! $this->isRunning($pid)) { + if (!$this->isRunning($pid)) { $this->error("Failed! There is no swoole_http_server process running."); - exit(1); + + return; } $this->info('Stopping swoole http server...'); @@ -117,7 +121,8 @@ protected function stop() if ($isRunning) { $this->error('Unable to stop the swoole_http_server process.'); - exit(1); + + return; } // I don't known why Swoole didn't trigger "onShutdown" after sending SIGTERM. @@ -132,7 +137,7 @@ protected function stop() */ protected function restart() { - $pid = $this->getPid(); + $pid = $this->getCurrentPid(); if ($this->isRunning($pid)) { $this->stop(); @@ -146,20 +151,22 @@ protected function restart() */ protected function reload() { - $pid = $this->getPid(); + $pid = $this->getCurrentPid(); - if (! $this->isRunning($pid)) { + if (!$this->isRunning($pid)) { $this->error("Failed! There is no swoole_http_server process running."); - exit(1); + + return; } $this->info('Reloading swoole_http_server...'); $isRunning = $this->killProcess($pid, SIGUSR1); - if (! $isRunning) { + if (!$isRunning) { $this->error('> failure'); - exit(1); + + return; } $this->info('> success'); @@ -175,20 +182,18 @@ protected function infos() /** * Display PHP and Swoole miscs infos. - * - * @param bool $more */ protected function showInfos() { - $pid = $this->getPid(); + $pid = $this->getCurrentPid(); $isRunning = $this->isRunning($pid); - $host = $this->configs['server']['host']; - $port = $this->configs['server']['port']; - $reactorNum = $this->configs['server']['options']['reactor_num']; - $workerNum = $this->configs['server']['options']['worker_num']; - $taskWorkerNum = $this->configs['server']['options']['task_worker_num']; - $isWebsocket = $this->configs['websocket']['enabled']; - $logFile = $this->configs['server']['options']['log_file']; + $host = Arr::get($this->config, 'server.host'); + $port = Arr::get($this->config, 'server.port'); + $reactorNum = Arr::get($this->config, 'server.options.reactor_num'); + $workerNum = Arr::get($this->config, 'server.options.worker_num'); + $taskWorkerNum = Arr::get($this->config, 'server.options.task_worker_num'); + $isWebsocket = Arr::get($this->config, 'websocket.enabled'); + $logFile = Arr::get($this->config, 'server.options.log_file'); $table = [ ['PHP Version', 'Version' => phpversion()], @@ -215,9 +220,10 @@ protected function initAction() { $this->action = $this->argument('action'); - if (! in_array($this->action, ['start', 'stop', 'restart', 'reload', 'infos'])) { + if (!in_array($this->action, ['start', 'stop', 'restart', 'reload', 'infos'], true)) { $this->error("Invalid argument '{$this->action}'. Expected 'start', 'stop', 'restart', 'reload' or 'infos'."); - exit(1); + + return; } } @@ -225,11 +231,12 @@ protected function initAction() * If Swoole process is running. * * @param int $pid + * * @return bool */ protected function isRunning($pid) { - if (! $pid) { + if (!$pid) { return false; } @@ -246,6 +253,7 @@ protected function isRunning($pid) * @param int $pid * @param int $sig * @param int $wait + * * @return bool */ protected function killProcess($pid, $sig, $wait = 0) @@ -256,7 +264,7 @@ protected function killProcess($pid, $sig, $wait = 0) $start = time(); do { - if (! $this->isRunning($pid)) { + if (!$this->isRunning($pid)) { break; } @@ -272,26 +280,17 @@ protected function killProcess($pid, $sig, $wait = 0) * * @return int|null */ - protected function getPid() + protected function getCurrentPid() { - if ($this->pid) { - return $this->pid; + if ($this->currentPid) { + return $this->currentPid; } - $pid = null; $path = $this->getPidPath(); - if (file_exists($path)) { - $pid = (int) file_get_contents($path); - - if (! $pid) { - $this->removePidFile(); - } else { - $this->pid = $pid; - } - } - - return $this->pid; + return $this->currentPid = file_exists($path) + ? (int)file_get_contents($path) ?? $this->removePidFile() + : null; } /** @@ -301,7 +300,7 @@ protected function getPid() */ protected function getPidPath() { - return $this->configs['server']['options']['pid_file']; + return Arr::get($this->config, 'server.options.pid_file', storage_path('logs/swoole.pid')); } /** @@ -317,9 +316,9 @@ protected function removePidFile() /** * Return daemonize config. */ - protected function isDaemon() + protected function isDaemon(): bool { - return $this->configs['server']['options']['daemonize']; + return Arr::get($this->config, 'server.options.daemonize', false); } /** @@ -329,13 +328,16 @@ protected function checkEnvironment() { if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { $this->error("Swoole extension doesn't support Windows OS yet."); - exit; - } elseif (! extension_loaded('swoole')) { + + return; + } else if (!extension_loaded('swoole')) { $this->error("Can't detect Swoole extension installed."); - exit; - } elseif (! version_compare(swoole_version(), '4.0.0', 'ge')) { + + return; + } else if (!version_compare(swoole_version(), '4.0.0', 'ge')) { $this->error("Your Swoole version must be higher than 4.0 to use coroutine."); - exit; + + return; } } } diff --git a/src/Concerns/InteractsWithSwooleTable.php b/src/Concerns/InteractsWithSwooleTable.php index 443eaf52..aa9e1b17 100644 --- a/src/Concerns/InteractsWithSwooleTable.php +++ b/src/Concerns/InteractsWithSwooleTable.php @@ -2,22 +2,30 @@ namespace SwooleTW\Http\Concerns; + +use Illuminate\Contracts\Console\Application as ConsoleApp; use Swoole\Table; use SwooleTW\Http\Table\SwooleTable; +/** + * Trait InteractsWithSwooleTable + * + * @property \Illuminate\Contracts\Container\Container $container + * @property \Illuminate\Contracts\Container\Container $app + */ trait InteractsWithSwooleTable { /** - * @var \SwooleTW\Http\Server\Table + * @var \SwooleTW\Http\Table\SwooleTable */ - protected $table; + protected $currentTable; /** * Register customized swoole talbes. */ protected function createTables() { - $this->table = new SwooleTable; + $this->currentTable = new SwooleTable; $this->registerTables(); } @@ -26,7 +34,7 @@ protected function createTables() */ protected function registerTables() { - $tables = $this->container['config']->get('swoole_http.tables', []); + $tables = $this->container->make('config')->get('swoole_http.tables', []); foreach ($tables as $key => $value) { $table = new Table($value['size']); @@ -40,7 +48,7 @@ protected function registerTables() } $table->create(); - $this->table->add($key, $table); + $this->currentTable->add($key, $table); } } @@ -49,9 +57,12 @@ protected function registerTables() */ protected function bindSwooleTable() { - $this->app->singleton(SwooleTable::class, function () { - return $this->table; - }); - $this->app->alias(SwooleTable::class, 'swoole.table'); + if (!$this->app instanceof ConsoleApp) { + $this->app->singleton(SwooleTable::class, function () { + return $this->currentTable; + }); + + $this->app->alias(SwooleTable::class, 'swoole.table'); + } } } diff --git a/src/Concerns/InteractsWithWebsocket.php b/src/Concerns/InteractsWithWebsocket.php index c22e1cfc..66bff107 100644 --- a/src/Concerns/InteractsWithWebsocket.php +++ b/src/Concerns/InteractsWithWebsocket.php @@ -2,33 +2,43 @@ namespace SwooleTW\Http\Concerns; -use Throwable; -use Swoole\Websocket\Frame; -use Swoole\Websocket\Server; + +use Illuminate\Contracts\Container\Container; use Illuminate\Pipeline\Pipeline; -use SwooleTW\Http\Websocket\Parser; -use Illuminate\Support\Facades\Facade; -use SwooleTW\Http\Websocket\Websocket; +use Illuminate\Support\Arr; +use SwooleTW\Http\Exceptions\WebsocketNotSetInConfigException; +use SwooleTW\Http\Helpers\Service; use SwooleTW\Http\Transformers\Request; use SwooleTW\Http\Websocket\HandlerContract; +use SwooleTW\Http\Websocket\Parser; +use SwooleTW\Http\Websocket\Push; use SwooleTW\Http\Websocket\Rooms\RoomContract; +use SwooleTW\Http\Websocket\Websocket; +use Throwable; +/** + * Trait InteractsWithWebsocket + * + * @property \Illuminate\Contracts\Container\Container $container + * @property \Illuminate\Contracts\Container\Container $app + * @property array $types + */ trait InteractsWithWebsocket { /** * @var boolean */ - protected $isWebsocket = false; + protected $isServerWebsocket = false; /** - * @var SwooleTW\Http\Websocket\HandlerContract + * @var \SwooleTW\Http\Websocket\HandlerContract */ protected $websocketHandler; /** - * @var SwooleTW\Http\Websocket\Parser + * @var \SwooleTW\Http\Websocket\Parser */ - protected $parser; + protected $payloadParser; /** * Websocket server events. @@ -40,34 +50,35 @@ trait InteractsWithWebsocket /** * "onOpen" listener. * - * @param \Swoole\Websocket\Server $server * @param \Swoole\Http\Request $swooleRequest */ - public function onOpen($server, $swooleRequest) + public function onOpen($swooleRequest) { $illuminateRequest = Request::make($swooleRequest)->toIlluminate(); + $websocket = $this->app->make(Service::WEBSOCKET_ALIAS); + $sandbox = $this->app->make(Service::SANDBOX_ALIAS); try { - $this->app['swoole.websocket']->reset(true)->setSender($swooleRequest->fd); + $websocket->reset(true)->setSender($swooleRequest->fd); // set currnt request to sandbox - $this->app['swoole.sandbox']->setRequest($illuminateRequest); + $sandbox->setRequest($illuminateRequest); // enable sandbox - $this->app['swoole.sandbox']->enable(); + $sandbox->enable(); // check if socket.io connection established - if (! $this->websocketHandler->onOpen($swooleRequest->fd, $illuminateRequest)) { + if (!$this->websocketHandler->onOpen($swooleRequest->fd, $illuminateRequest)) { return; } // trigger 'connect' websocket event - if ($this->app['swoole.websocket']->eventExists('connect')) { + if ($websocket->eventExists('connect')) { // set sandbox container to websocket pipeline - $this->app['swoole.websocket']->setContainer($this->app['swoole.sandbox']->getApplication()); - $this->app['swoole.websocket']->call('connect', $illuminateRequest); + $websocket->setContainer($sandbox->getApplication()); + $websocket->call('connect', $illuminateRequest); } } catch (Throwable $e) { $this->logServerError($e); } finally { // disable and recycle sandbox resource - $this->app['swoole.sandbox']->disable(); + $sandbox->disable(); } } @@ -79,31 +90,33 @@ public function onOpen($server, $swooleRequest) */ public function onMessage($server, $frame) { - try { - // execute parser strategies and skip non-message packet - if ($this->parser->execute($server, $frame)) { - return; - } + // execute parser strategies and skip non-message packet + if ($this->payloadParser->execute($server, $frame)) { + return; + } + + $websocket = $this->app->make(Service::WEBSOCKET_ALIAS); + $sandbox = $this->app->make(Service::SANDBOX_ALIAS); + try { // decode raw message via parser - $payload = $this->parser->decode($frame); + $payload = $this->payloadParser->decode($frame); - $this->app['swoole.websocket']->reset(true)->setSender($frame->fd); + $websocket->reset(true)->setSender($frame->fd); // enable sandbox - $this->app['swoole.sandbox']->enable(); + $sandbox->enable(); // dispatch message to registered event callback - if ($this->app['swoole.websocket']->eventExists($payload['event'])) { - $this->app['swoole.websocket']->call($payload['event'], $payload['data']); - } else { - $this->websocketHandler->onMessage($frame); - } + ['event' => $event, 'data' => $data] = $payload; + $websocket->eventExists($event) + ? $websocket->call($event, $data) + : $this->websocketHandler->onMessage($frame); } catch (Throwable $e) { $this->logServerError($e); } finally { // disable and recycle sandbox resource - $this->app['swoole.sandbox']->disable(); + $sandbox->disable(); } } @@ -116,20 +129,22 @@ public function onMessage($server, $frame) */ public function onClose($server, $fd, $reactorId) { - if (! $this->isWebsocket($fd)) { + if (!$this->isServerWebsocket($fd) || !$server instanceof Websocket) { return; } + $websocket = $this->app->make(Service::WEBSOCKET_ALIAS); + try { - $this->app['swoole.websocket']->reset(true)->setSender($fd); + $websocket->reset(true)->setSender($fd); // trigger 'disconnect' websocket event - if ($this->app['swoole.websocket']->eventExists('disconnect')) { - $this->app['swoole.websocket']->call('disconnect'); + if ($websocket->eventExists('disconnect')) { + $websocket->call('disconnect'); } else { $this->websocketHandler->onClose($fd, $reactorId); } // leave all rooms - $this->app['swoole.websocket']->leave(); + $websocket->leave(); } catch (Throwable $e) { $this->logServerError($e); } @@ -143,40 +158,37 @@ public function onClose($server, $fd, $reactorId) */ public function pushMessage($server, array $data) { - [$opcode, $sender, $fds, $broadcast, $assigned, $event, $message] = $this->normalizePushData($data); - $message = $this->parser->encode($event, $message); + $push = Push::new($data); + $payload = $this->payloadParser->encode($push->getEvent(), $push->getMessage()); // attach sender if not broadcast - if (! $broadcast && $sender && ! in_array($sender, $fds)) { - $fds[] = $sender; + if (!$push->isBroadcast() && $push->getSender() && !$push->hasOwnDescriptor()) { + $push->addDescriptor($push->getSender()); } // check if to broadcast all clients - if ($broadcast && empty($fds) && ! $assigned) { - foreach ($server->connections as $fd) { - if ($this->isWebsocket($fd)) { - $fds[] = $fd; - } - } + if ($push->isBroadcastToAllDescriptors()) { + $push->mergeDescriptor($this->filterWebsocket($server->connections)); } // push message to designated fds - foreach ($fds as $fd) { - if (($broadcast && $sender === (integer) $fd) || ! $server->exist($fd)) { - continue; + foreach ($push->getDescriptors() as $descriptor) { + if ($server->exist($descriptor) || !$push->isBroadcastToDescriptor((int)$descriptor)) { + $server->push($descriptor, $payload, $push->getOpcode()); } - $server->push($fd, $message, $opcode); } } /** * Set frame parser for websocket. * - * @param \SwooleTW\Http\Websocket\Parser $parser + * @param \SwooleTW\Http\Websocket\Parser $payloadParser + * + * @return \SwooleTW\Http\Concerns\InteractsWithWebsocket */ - public function setParser(Parser $parser) + public function setPayloadParser(Parser $payloadParser) { - $this->parser = $parser; + $this->payloadParser = $payloadParser; return $this; } @@ -184,9 +196,9 @@ public function setParser(Parser $parser) /** * Get frame parser for websocket. */ - public function getParser() + public function getPayloadParser() { - return $this->parser; + return $this->payloadParser; } /** @@ -194,35 +206,58 @@ public function getParser() */ protected function prepareWebsocket() { - $isWebsocket = $this->container['config']->get('swoole_http.websocket.enabled'); - $parser = $this->container['config']->get('swoole_websocket.parser'); + $config = $this->container->make(Service::CONFIG_ALIAS); + $isWebsocket = $config->get('swoole_http.websocket.enabled'); + $parser = $config->get('swoole_websocket.parser'); if ($isWebsocket) { - array_push($this->events, ...$this->wsEvents); - $this->isWebsocket = true; - $this->setParser(new $parser); + $this->types = array_merge($this->types ?? [], $this->wsEvents); + $this->isServerWebsocket = true; + $this->setPayloadParser(new $parser); } } /** * Check if it's a websocket fd. + * + * @param int $fd + * + * @return bool */ - protected function isWebsocket(int $fd) + protected function isServerWebsocket(int $fd): bool { - $info = $this->container['swoole.server']->connection_info($fd); + $info = $this->container->make(Service::SERVER_ALIAS)->connection_info($fd); - return array_key_exists('websocket_status', $info) && $info['websocket_status']; + return Arr::has($info, 'websocket_status') && Arr::get($info, 'websocket_status'); + } + + /** + * Returns all descriptors that are websocket + * + * @param array $descriptors + * + * @return array + */ + protected function filterWebsocket(array $descriptors): array + { + $callback = function ($descriptor) { + return $this->isServerWebsocket($descriptor); + }; + + return collect($descriptors)->filter($callback)->toArray(); } /** * Prepare websocket handler for onOpen and onClose callback. + * + * @throws \Exception */ protected function prepareWebsocketHandler() { - $handlerClass = $this->container['config']->get('swoole_websocket.handler'); + $handlerClass = $this->container->make(Service::CONFIG_ALIAS)->get('swoole_websocket.handler'); - if (! $handlerClass) { - throw new Exception('Websocket handler is not set in swoole_websocket config'); + if (!$handlerClass) { + throw new WebsocketNotSetInConfigException; } $this->setWebsocketHandler($this->app->make($handlerClass)); @@ -230,6 +265,10 @@ protected function prepareWebsocketHandler() /** * Set websocket handler. + * + * @param \SwooleTW\Http\Websocket\HandlerContract $handler + * + * @return \SwooleTW\Http\Concerns\InteractsWithWebsocket */ public function setWebsocketHandler(HandlerContract $handler) { @@ -240,35 +279,39 @@ public function setWebsocketHandler(HandlerContract $handler) /** * Get websocket handler. + * + * @return \SwooleTW\Http\Websocket\HandlerContract */ - public function getWebsocketHandler() + public function getWebsocketHandler(): HandlerContract { return $this->websocketHandler; } /** - * Get websocket handler for onOpen and onClose callback. + * @param string $class + * @param array $settings + * + * @return \SwooleTW\Http\Websocket\Rooms\RoomContract */ - protected function getWebsocketRoom() + protected function createRoom(string $class, array $settings): RoomContract { - $driver = $this->container['config']->get('swoole_websocket.default'); - $configs = $this->container['config']->get("swoole_websocket.settings.{$driver}"); - $className = $this->container['config']->get("swoole_websocket.drivers.{$driver}"); - - $websocketRoom = new $className($configs); - $websocketRoom->prepare(); - - return $websocketRoom; + return new $class($settings); } /** * Bind room instance to Laravel app container. */ - protected function bindRoom() + protected function bindRoom(): void { - $this->app->singleton(RoomContract::class, function ($app) { - return $this->getWebsocketRoom(); + $this->app->singleton(RoomContract::class, function (Container $container) { + $config = $container->make(Service::CONFIG_ALIAS); + $driver = $config->get('swoole_websocket.default'); + $settings = $config->get("swoole_websocket.settings.{$driver}"); + $className = $config->get("swoole_websocket.drivers.{$driver}"); + + return $this->createRoom($className, $settings); }); + $this->app->alias(RoomContract::class, 'swoole.room'); } @@ -277,10 +320,11 @@ protected function bindRoom() */ protected function bindWebsocket() { - $this->app->singleton(Websocket::class, function ($app) { - return new Websocket($app['swoole.room'], new Pipeline($app)); + $this->app->singleton(Websocket::class, function (Container $app) { + return new Websocket($app->make(Service::ROOM_ALIAS), new Pipeline($app)); }); - $this->app->alias(Websocket::class, 'swoole.websocket'); + + $this->app->alias(Websocket::class, Service::WEBSOCKET_ALIAS); } /** @@ -288,9 +332,9 @@ protected function bindWebsocket() */ protected function loadWebsocketRoutes() { - $routePath = $this->container['config']->get('swoole_websocket.route_file'); + $routePath = $this->container->make(Service::CONFIG_ALIAS)->get('swoole_websocket.route_file'); - if (! file_exists($routePath)) { + if (!file_exists($routePath)) { $routePath = __DIR__ . '/../../routes/websocket.php'; } @@ -299,16 +343,20 @@ protected function loadWebsocketRoutes() /** * Normalize data for message push. + * + * @param array $data + * + * @return array */ public function normalizePushData(array $data) { - $opcode = $data['opcode'] ?? 1; - $sender = $data['sender'] ?? 0; - $fds = $data['fds'] ?? []; - $broadcast = $data['broadcast'] ?? false; - $assigned = $data['assigned'] ?? false; - $event = $data['event'] ?? null; - $message = $data['message'] ?? null; + $opcode = Arr::get($data, 'opcode', 1); + $sender = Arr::get($data, 'sender', 0); + $fds = Arr::get($data, 'fds', []); + $broadcast = Arr::get($data, 'broadcast', false); + $assigned = Arr::get($data, 'assigned', false); + $event = Arr::get($data, 'event', null); + $message = Arr::get($data, 'message', null); return [$opcode, $sender, $fds, $broadcast, $assigned, $event, $message]; } diff --git a/src/Concerns/ResetApplication.php b/src/Concerns/ResetApplication.php index 6f86569f..4e611a3e 100644 --- a/src/Concerns/ResetApplication.php +++ b/src/Concerns/ResetApplication.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http\Concerns; + use Illuminate\Contracts\Container\Container; use SwooleTW\Http\Exceptions\SandboxException; use SwooleTW\Http\Server\Resetters\ResetterContract; @@ -19,7 +20,7 @@ trait ResetApplication protected $providers = []; /** - * @var array + * @var \SwooleTW\Http\Server\Resetters\ResetterContract[]|array */ protected $resetters = []; @@ -48,7 +49,7 @@ protected function setInitialProviders() $providers = $this->config->get('swoole_http.providers', []); foreach ($providers as $provider) { - if (class_exists($provider) && ! in_array($provider, $this->providers)) { + if (class_exists($provider) && !in_array($provider, $this->providers)) { $providerClass = new $provider($app); $this->providers[$provider] = $providerClass; } @@ -73,7 +74,7 @@ protected function setInitialResetters() foreach ($resetters as $resetter) { $resetterClass = $app->make($resetter); - if (! $resetterClass instanceof ResetterContract) { + if (!$resetterClass instanceof ResetterContract) { throw new SandboxException("{$resetter} must implement " . ResetterContract::class); } $this->resetters[$resetter] = $resetterClass; @@ -90,6 +91,8 @@ public function getResetters() /** * Reset Laravel/Lumen Application. + * + * @param \Illuminate\Contracts\Container\Container $app */ public function resetApp(Container $app) { diff --git a/src/Concerns/WithApplication.php b/src/Concerns/WithApplication.php index d34385dc..46053cbf 100644 --- a/src/Concerns/WithApplication.php +++ b/src/Concerns/WithApplication.php @@ -2,33 +2,39 @@ namespace SwooleTW\Http\Concerns; -use Illuminate\Http\Request; + +use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Http\Kernel; use Illuminate\Support\Facades\Facade; -use Illuminate\Contracts\Container\Container; -use Laravel\Lumen\Application as LumenApplication; -use Symfony\Component\HttpFoundation\StreamedResponse; -use Symfony\Component\HttpFoundation\BinaryFileResponse; -use Symfony\Component\HttpFoundation\Response as SymfonyResponse; - +use SwooleTW\Http\Exceptions\FrameworkNotSupportException; +use SwooleTW\Http\Helpers\Service; + +/** + * Trait WithApplication + * + * @property Container $container + * @property string $framework + */ trait WithApplication { /** * Laravel|Lumen Application. * - * @var \Illuminate\Contracts\Container\Container + * @var \Illuminate\Contracts\Container\Container|mixed */ protected $app; /** * Bootstrap framework. + * + * @throws \ReflectionException */ protected function bootstrap() { if ($this->framework === 'laravel') { $bootstrappers = $this->getBootstrappers(); $this->app->bootstrapWith($bootstrappers); - } elseif (is_null(Facade::getFacadeApplication())) { + } else if (is_null(Facade::getFacadeApplication())) { $this->app->withFacades(); } @@ -42,15 +48,16 @@ protected function bootstrap() */ protected function loadApplication() { - return require $this->basePath . '/bootstrap/app.php'; + return require "{$this->basePath}/bootstrap/app.php"; } /** - * @return \Illuminate\Contracts\Container\Container + * @return \Illuminate\Contracts\Container\Container|mixed + * @throws \ReflectionException */ public function getApplication() { - if (! $this->app instanceof Container) { + if (!$this->app instanceof Container) { $this->app = $this->loadApplication(); $this->bootstrap(); } @@ -60,6 +67,8 @@ public function getApplication() /** * Set laravel application. + * + * @param \Illuminate\Contracts\Container\Container $app */ public function setApplication(Container $app) { @@ -70,6 +79,7 @@ public function setApplication(Container $app) * Get bootstrappers. * * @return array + * @throws \ReflectionException */ protected function getBootstrappers() { @@ -91,14 +101,15 @@ protected function getBootstrappers() * Set framework. * * @param string $framework + * * @throws \Exception */ protected function setFramework($framework) { $framework = strtolower($framework); - if (! in_array($framework, ['laravel', 'lumen'])) { - throw new \Exception(sprintf('Not support framework "%s".', $framework)); + if (!in_array($framework, ['laravel', 'lumen'])) { + throw new FrameworkNotSupportException($framework); } $this->framework = $framework; @@ -132,10 +143,12 @@ public function getBasePath() /** * Reslove some instances before request. + * + * @throws \ReflectionException */ protected function preResolveInstances() { - $resolves = $this->container['config']->get('swoole_http.pre_resolved', []); + $resolves = $this->container->make(Service::CONFIG_ALIAS)->get('swoole_http.pre_resolved', []); foreach ($resolves as $abstract) { if ($this->getApplication()->offsetExists($abstract)) { diff --git a/src/Controllers/SocketIOController.php b/src/Controllers/SocketIOController.php index be16a5ac..48819983 100644 --- a/src/Controllers/SocketIOController.php +++ b/src/Controllers/SocketIOController.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http\Controllers; + use Illuminate\Http\Request; use Illuminate\Support\Facades\Config; @@ -11,10 +12,10 @@ class SocketIOController public function upgrade(Request $request) { - if (! in_array($request->input('transport'), $this->transports)) { + if (!in_array($request->input('transport'), $this->transports)) { return response()->json([ 'code' => 0, - 'message' => 'Transport unknown' + 'message' => 'Transport unknown', ], 400); } @@ -26,17 +27,17 @@ public function upgrade(Request $request) 'sid' => base64_encode(uniqid()), 'upgrades' => ['websocket'], 'pingInterval' => Config::get('swoole_websocket.ping_interval'), - 'pingTimeout' => Config::get('swoole_websocket.ping_timeout') + 'pingTimeout' => Config::get('swoole_websocket.ping_timeout'), ]); return '97:0' . $payload . '2:40'; } - public function reject(Request $request) + public function reject() { return response()->json([ 'code' => 3, - 'message' => 'Bad request' + 'message' => 'Bad request', ], 400); } } diff --git a/src/Coroutine/ConnectionException.php b/src/Coroutine/ConnectionException.php index f5ae28c0..1698f80b 100644 --- a/src/Coroutine/ConnectionException.php +++ b/src/Coroutine/ConnectionException.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http\Coroutine; + class ConnectionException extends \Exception { // diff --git a/src/Coroutine/Connectors/ConnectorFactory.php b/src/Coroutine/Connectors/ConnectorFactory.php new file mode 100644 index 00000000..37dcb51a --- /dev/null +++ b/src/Coroutine/Connectors/ConnectorFactory.php @@ -0,0 +1,106 @@ +getDocComment(), $result)) { + $fileVersion = Arr::first($result); + } + } + + return version_compare($fileVersion, $version, '>='); + } catch (\Exception $e) { + return false; + } + } + + /** + * @param string $version + * + * @return bool + */ + protected static function hasBreakingChanges(string $version): bool + { + return version_compare($version, self::CHANGE_VERSION, '>='); + } +} diff --git a/src/Coroutine/Connectors/MySqlConnector.php b/src/Coroutine/Connectors/MySqlConnector.php index 627aadd8..7082d761 100644 --- a/src/Coroutine/Connectors/MySqlConnector.php +++ b/src/Coroutine/Connectors/MySqlConnector.php @@ -2,21 +2,27 @@ namespace SwooleTW\Http\Coroutine\Connectors; -use Exception; + +use Illuminate\Database\Connectors\MySqlConnector as BaseConnector; use Illuminate\Support\Str; use SwooleTW\Http\Coroutine\PDO as SwoolePDO; -use Illuminate\Database\Connectors\MySqlConnector as BaseConnector; +use Throwable; +/** + * Class MySqlConnector (5.6) + */ class MySqlConnector extends BaseConnector { /** * Create a new PDO connection instance. * - * @param string $dsn - * @param string $username - * @param string $password - * @param array $options + * @param string $dsn + * @param string $username + * @param string $password + * @param array $options + * * @return \PDO + * @throws \SwooleTW\Http\Coroutine\ConnectionException */ protected function createPdoConnection($dsn, $username, $password, $options) { @@ -26,16 +32,16 @@ protected function createPdoConnection($dsn, $username, $password, $options) /** * Handle an exception that occurred during connect execution. * - * @param \Exception $e - * @param string $dsn - * @param string $username - * @param string $password - * @param array $options - * @return \PDO + * @param \Throwable $e + * @param string $dsn + * @param string $username + * @param string $password + * @param array $options * - * @throws \Exception + * @return \PDO + * @throws \Throwable */ - protected function tryAgainIfCausedByLostConnection(Exception $e, $dsn, $username, $password, $options) + protected function tryAgainIfCausedByLostConnection(Throwable $e, $dsn, $username, $password, $options) { // https://github.com/swoole/swoole-src/blob/a414e5e8fec580abb3dbd772d483e12976da708f/swoole_mysql_coro.c#L196 if ($this->causedByLostConnection($e) || Str::contains($e->getMessage(), 'is closed')) { diff --git a/src/Coroutine/Context.php b/src/Coroutine/Context.php index a2f49a34..9f118229 100644 --- a/src/Coroutine/Context.php +++ b/src/Coroutine/Context.php @@ -2,8 +2,9 @@ namespace SwooleTW\Http\Coroutine; -use Swoole\Coroutine; + use Illuminate\Contracts\Container\Container; +use Swoole\Coroutine; class Context { @@ -31,6 +32,8 @@ public static function getApp() /** * Set app container by current coroutine id. + * + * @param \Illuminate\Contracts\Container\Container $app */ public static function setApp(Container $app) { @@ -39,6 +42,10 @@ public static function setApp(Container $app) /** * Get data by current coroutine id. + * + * @param string $key + * + * @return mixed|null */ public static function getData(string $key) { @@ -47,6 +54,9 @@ public static function getData(string $key) /** * Set data by current coroutine id. + * + * @param string $key + * @param $value */ public static function setData(string $key, $value) { @@ -55,6 +65,8 @@ public static function setData(string $key, $value) /** * Remove data by current coroutine id. + * + * @param string $key */ public static function removeData(string $key) { @@ -62,7 +74,7 @@ public static function removeData(string $key) } /** - * Get data by current coroutine id. + * Get data keys by current coroutine id. */ public static function getDataKeys() { @@ -70,7 +82,7 @@ public static function getDataKeys() } /** - * Get data by current coroutine id. + * Clear data by current coroutine id. */ public static function clear() { diff --git a/src/Coroutine/MySqlConnection.php b/src/Coroutine/MySqlConnection.php index be73c294..27e972b5 100644 --- a/src/Coroutine/MySqlConnection.php +++ b/src/Coroutine/MySqlConnection.php @@ -2,20 +2,22 @@ namespace SwooleTW\Http\Coroutine; + use Closure; -use Illuminate\Support\Str; -use Illuminate\Database\QueryException; use Illuminate\Database\MySqlConnection as BaseConnection; +use Illuminate\Database\QueryException; +use Illuminate\Support\Str; class MySqlConnection extends BaseConnection { /** * Handle a query exception that occurred during query execution. * - * @param \Illuminate\Database\QueryException $e - * @param string $query - * @param array $bindings - * @param \Closure $callback + * @param \Illuminate\Database\QueryException $e + * @param string $query + * @param array $bindings + * @param \Closure $callback + * * @return mixed * * @throws \Illuminate\Database\QueryException diff --git a/src/Coroutine/PDO.php b/src/Coroutine/PDO.php index 5e4a7aeb..c79e2af9 100644 --- a/src/Coroutine/PDO.php +++ b/src/Coroutine/PDO.php @@ -9,27 +9,30 @@ namespace SwooleTW\Http\Coroutine; + use Exception; -use PDO as BasePDO; use Illuminate\Database\QueryException; -use SwooleTW\Http\Coroutine\PDOStatement; -use SwooleTW\Http\Coroutine\StatementException; -use SwooleTW\Http\Coroutine\ConnectionException; +use Illuminate\Support\Arr; +use PDO as BasePDO; +/** + * Class PDO + */ class PDO extends BasePDO { public static $keyMap = [ - 'dbname' => 'database' + 'dbname' => 'database', ]; - private static $defaultOptions = [ + private static $options = [ 'host' => '', 'port' => 3306, 'user' => '', 'password' => '', 'database' => '', 'charset' => 'utf8mb4', - 'strict_type' => true + 'strict_type' => true, + 'timeout' => -1, ]; /** @var \Swoole\Coroutine\Mysql */ @@ -37,26 +40,42 @@ class PDO extends BasePDO public $inTransaction = false; - public function __construct( - string $dsn, - string $username = '', - string $password = '', - array $driverOptions = [] - ) { + /** + * PDO constructor. + * + * @param string $dsn + * @param string $username + * @param string $password + * @param array $options + * + * @throws \SwooleTW\Http\Coroutine\ConnectionException + */ + public function __construct(string $dsn, string $username = '', string $password = '', array $options = []) + { + parent::__construct($dsn, $username, $password, $options); $this->setClient(); $this->connect($this->getOptions(...func_get_args())); } + /** + * @param mixed $client + */ protected function setClient($client = null) { $this->client = $client ?: new \Swoole\Coroutine\Mysql(); } + /** + * @param array $options + * + * @return $this + * @throws \SwooleTW\Http\Coroutine\ConnectionException + */ protected function connect(array $options = []) { $this->client->connect($options); - if (! $this->client->connected) { + if (!$this->client->connected) { $message = $this->client->connect_error ?: $this->client->error; $errorCode = $this->client->connect_errno ?: $this->client->errno; @@ -66,19 +85,27 @@ protected function connect(array $options = []) return $this; } + /** + * @param $dsn + * @param $username + * @param $password + * @param $driverOptions + * + * @return array + */ protected function getOptions($dsn, $username, $password, $driverOptions) { $dsn = explode(':', $dsn); $driver = ucwords(array_shift($dsn)); $dsn = explode(';', implode(':', $dsn)); - $options = []; + $configuredOptions = []; static::checkDriver($driver); foreach ($dsn as $kv) { $kv = explode('=', $kv); - if ($kv) { - $options[$kv[0]] = $kv[1] ?? ''; + if (count($kv)) { + $configuredOptions[$kv[0]] = $kv[1] ?? ''; } } @@ -87,63 +114,92 @@ protected function getOptions($dsn, $username, $password, $driverOptions) 'password' => $password, ]; - $options = $driverOptions + $authorization + $options; + $configuredOptions = $driverOptions + $authorization + $configuredOptions; foreach (static::$keyMap as $pdoKey => $swpdoKey) { - if (isset($options[$pdoKey])) { - $options[$swpdoKey] = $options[$pdoKey]; - unset($options[$pdoKey]); + if (isset($configuredOptions[$pdoKey])) { + $configuredOptions[$swpdoKey] = $configuredOptions[$pdoKey]; + unset($configuredOptions[$pdoKey]); } } - return $options + static::$defaultOptions; + return array_merge($configuredOptions, static::$options); } + /** + * @param string $driver + */ public static function checkDriver(string $driver) { - if (! in_array($driver, static::getAvailableDrivers())) { + if (!in_array($driver, static::getAvailableDrivers())) { throw new \InvalidArgumentException("{$driver} driver is not supported yet."); } } + /** + * @return array + */ public static function getAvailableDrivers() { return ['Mysql']; } + /** + * @return bool|void + */ public function beginTransaction() { $this->client->begin(); $this->inTransaction = true; } + /** + * @return bool|void + */ public function rollBack() { $this->client->rollback(); $this->inTransaction = false; } + /** + * @return bool|void + */ public function commit() { $this->client->commit(); $this->inTransaction = true; } + /** + * @return bool + */ public function inTransaction() { return $this->inTransaction; } + /** + * @param null $seqname + * + * @return int|string + */ public function lastInsertId($seqname = null) { return $this->client->insert_id; } + /** + * @return mixed|void + */ public function errorCode() { $this->client->errno; } + /** + * @return array + */ public function errorInfo() { return [ @@ -153,6 +209,11 @@ public function errorInfo() ]; } + /** + * @param string $statement + * + * @return int + */ public function exec($statement): int { $this->query($statement); @@ -160,9 +221,17 @@ public function exec($statement): int return $this->client->affected_rows; } - public function query(string $statement, float $timeout = -1) + /** + * @param string $statement + * @param int $mode + * @param mixed $arg3 + * @param array $ctorargs + * + * @return array|bool|false|\PDOStatement + */ + public function query($statement, $mode = PDO::ATTR_DEFAULT_FETCH_MODE, $arg3 = null, array $ctorargs = []) { - $result = $this->client->query($statement, $timeout); + $result = $this->client->query($statement, Arr::get(self::$options, 'timeout')); if ($result === false) { $exception = new Exception($this->client->error, $this->client->errno); @@ -172,39 +241,44 @@ public function query(string $statement, float $timeout = -1) return $result; } - private function rewriteToPosition(string $statement) + /** + * @param string $statement + * @param array $options + * + * @return bool|\PDOStatement|\SwooleTW\Http\Coroutine\PDOStatement + */ + public function prepare($statement, $options = null) { - // - } - - public function prepare($statement, $driverOptions = null) - { - $driverOptions = is_null($driverOptions) ? [] : $driverOptions; + $options = is_null($options) ? [] : $options; if (strpos($statement, ':') !== false) { $i = 0; $bindKeyMap = []; $statement = preg_replace_callback( - '/:(\w+)\b/', + '/:([a-zA-Z_]\w*?)\b/', function ($matches) use (&$i, &$bindKeyMap) { $bindKeyMap[$matches[1]] = $i++; return '?'; - }, - $statement - ); + }, $statement); } $stmtObj = $this->client->prepare($statement); if ($stmtObj) { $stmtObj->bindKeyMap = $bindKeyMap ?? []; - return new PDOStatement($this, $stmtObj, $driverOptions); + + return new PDOStatement($this, $stmtObj, $options); } else { $statementException = new StatementException($this->client->error, $this->client->errno); throw new QueryException($statement, [], $statementException); } } + /** + * @param int $attribute + * + * @return bool|mixed|string + */ public function getAttribute($attribute) { switch ($attribute) { @@ -221,7 +295,7 @@ public function getAttribute($attribute) case \PDO::ATTR_PERSISTENT: case \PDO::ATTR_PREFETCH: case \PDO::ATTR_SERVER_INFO: - return $this->serverInfo['timeout'] ?? static::$defaultOptions['timeout']; + return self::$options['timeout']; case \PDO::ATTR_SERVER_VERSION: return 'Swoole Mysql'; case \PDO::ATTR_TIMEOUT: @@ -230,6 +304,12 @@ public function getAttribute($attribute) } } + /** + * @param string $string + * @param null $paramtype + * + * @return string|void + */ public function quote($string, $paramtype = null) { throw new \BadMethodCallException(<<client->close(); diff --git a/src/Coroutine/PDOStatement.php b/src/Coroutine/PDOStatement.php index bec3fa1a..b30ae1bf 100644 --- a/src/Coroutine/PDOStatement.php +++ b/src/Coroutine/PDOStatement.php @@ -9,21 +9,62 @@ namespace SwooleTW\Http\Coroutine; + use PDOStatement as BaseStatement; -use SwooleTW\Http\Coroutine\PDO; use Swoole\Coroutine\MySQL\Statement; +/** + * Class PDOStatement + */ class PDOStatement extends BaseStatement { + /** + * @var \SwooleTW\Http\Coroutine\PDO + */ private $parent; + + /** + * @var \Swoole\Coroutine\MySQL\Statement|mixed + */ public $statement; + + /** + * @var int|mixed + */ public $timeout; + + /** + * @var array + */ public $bindMap = []; + + /** + * @var int + */ public $cursor = -1; + + /** + * @var int + */ public $cursorOrientation = PDO::FETCH_ORI_NEXT; + + /** + * @var array + */ public $resultSet = []; + + /** + * @var int + */ public $fetchStyle = PDO::FETCH_BOTH; + /** + * PDOStatement constructor. + * + * @param \SwooleTW\Http\Coroutine\PDO $parent + * @param \Swoole\Coroutine\MySQL\Statement $statement + * @param array $driverOptions + */ public function __construct(PDO $parent, Statement $statement, array $driverOptions = []) { $this->parent = $parent; @@ -48,7 +89,7 @@ public function rowCount() public function bindParam($parameter, &$variable, $type = null, $maxlen = null, $driverdata = null) { - if (! is_string($parameter) && ! is_int($parameter)) { + if (!is_string($parameter) && !is_int($parameter)) { return false; } @@ -60,15 +101,15 @@ public function bindParam($parameter, &$variable, $type = null, $maxlen = null, public function bindValue($parameter, $variable, $type = null) { - if (! is_string($parameter) && ! is_int($parameter)) { + if (!is_string($parameter) && !is_int($parameter)) { return false; } if (is_object($variable)) { - if (! method_exists($variable, '__toString')) { + if (!method_exists($variable, '__toString')) { return false; } else { - $variable = (string) $variable; + $variable = (string)$variable; } } @@ -86,16 +127,18 @@ private function afterExecute() public function execute($inputParameters = null) { - if (! empty($inputParameters)) { + if (!empty($inputParameters)) { foreach ($inputParameters as $key => $value) { $this->bindParam($key, $value); } } $inputParameters = []; - if (! empty($this->statement->bindKeyMap)) { + if (!empty($this->statement->bindKeyMap)) { foreach ($this->statement->bindKeyMap as $nameKey => $numKey) { - $inputParameters[$numKey] = $this->bindMap[$nameKey]; + if (isset($this->bindMap[$nameKey])) { + $inputParameters[$numKey] = $this->bindMap[$nameKey]; + } } } else { $inputParameters = $this->bindMap; @@ -105,12 +148,18 @@ public function execute($inputParameters = null) $this->resultSet = ($ok = $result !== false) ? $result : []; $this->afterExecute(); + if ($result === false) { + throw new \PDOException($this->errorInfo(), $this->errorCode()); + } + return $ok; } - public function setFetchMode($fetchStyle, $params = null) + public function setFetchMode($fetchStyle, $params = null, array $ctorarfg = []) { $this->fetchStyle = $fetchStyle; + + return true; } private function __executeWhenStringQueryEmpty() @@ -137,13 +186,9 @@ private function transBoth($rawData) return $temp; } - private function transStyle( - $rawData, - $fetchStyle = null, - $fetchArgument = null, - $ctorArgs = null - ) { - if (! is_array($rawData)) { + private function transStyle($rawData, $fetchStyle = null, $fetchArgument = null, $ctorArgs = null) + { + if (!is_array($rawData)) { return false; } if (empty($rawData)) { @@ -151,7 +196,8 @@ private function transStyle( } $fetchStyle = is_null($fetchStyle) ? $this->fetchStyle : $fetchStyle; - $ctorArgs = is_null($ctorArgs) ? [] : $ctorArgs; + // TODO Use it if needed + #$ctorArgs = is_null($ctorArgs) ? [] : $ctorArgs; $resultSet = []; switch ($fetchStyle) { @@ -166,7 +212,7 @@ private function transStyle( break; case PDO::FETCH_OBJ: foreach ($rawData as $row) { - $resultSet[] = (object) $row; + $resultSet[] = (object)$row; } break; case PDO::FETCH_NUM: @@ -182,16 +228,12 @@ private function transStyle( return $resultSet; } - public function fetch( - $fetchStyle = null, - $cursorOrientation = null, - $cursorOffset = null, - $fetchArgument = null - ) { + public function fetch($fetchStyle = null, $cursorOrientation = null, $cursorOffset = null, $fetchArgument = null) + { $this->__executeWhenStringQueryEmpty(); - $cursorOrientation = is_null($cursorOrientation) ? PDO::FETCH_ORI_NEXT : $cursorOrientation; - $cursorOffset = is_null($cursorOffset) ? 0 : (int) $cursorOffset; + $cursorOrientation = \is_null($cursorOrientation) ? PDO::FETCH_ORI_NEXT : $cursorOrientation; + $cursorOffset = \is_null($cursorOffset) ? 0 : (int)$cursorOffset; switch ($cursorOrientation) { case PDO::FETCH_ORI_ABS: @@ -222,16 +264,15 @@ public function fetch( /** * Returns a single column from the next row of a result set or FALSE if there are no more rows. * - * @param int $column_number - * 0-indexed number of the column you wish to retrieve from the row. - * If no value is supplied, PDOStatement::fetchColumn() fetches the first column. + * @param int|null $columnNumber * * @return bool|mixed */ public function fetchColumn($columnNumber = null) { - $columnNumber = is_null($columnNumber) ? 0 : $columnNumber; + $columnNumber = \is_null($columnNumber) ? 0 : $columnNumber; $this->__executeWhenStringQueryEmpty(); + return $this->fetch(PDO::FETCH_COLUMN, PDO::FETCH_ORI_NEXT, 0, $columnNumber); } diff --git a/src/Coroutine/StatementException.php b/src/Coroutine/StatementException.php index ca839e08..9259bcbd 100644 --- a/src/Coroutine/StatementException.php +++ b/src/Coroutine/StatementException.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http\Coroutine; + class StatementException extends \Exception { // diff --git a/src/Exceptions/FrameworkNotSupportException.php b/src/Exceptions/FrameworkNotSupportException.php new file mode 100644 index 00000000..90401358 --- /dev/null +++ b/src/Exceptions/FrameworkNotSupportException.php @@ -0,0 +1,22 @@ +version(), $expression)) { + return $version; + } + + throw new LogicException('No any version found.'); + } + + /** + * Extracts lumen version from $app->version() + * + * @param string $version + * @param string $expression + * + * @return string|null + */ + protected static function extractVersion(string $version, string $expression): ?string + { + if (preg_match($expression, $version, $result)) { + return Arr::first($result); + } + + return null; + } +} \ No newline at end of file diff --git a/src/Helpers/OS.php b/src/Helpers/OS.php new file mode 100644 index 00000000..1104473b --- /dev/null +++ b/src/Helpers/OS.php @@ -0,0 +1,55 @@ +publishes([ __DIR__ . '/../config/swoole_http.php' => base_path('config/swoole_http.php'), __DIR__ . '/../config/swoole_websocket.php' => base_path('config/swoole_websocket.php'), - __DIR__ . '/../routes/websocket.php' => base_path('routes/websocket.php') + __DIR__ . '/../routes/websocket.php' => base_path('routes/websocket.php'), ], 'laravel-swoole'); - if ($this->app['config']->get('swoole_http.websocket.enabled')) { + if ($this->app->make(Service::CONFIG_ALIAS)->get('swoole_http.websocket.enabled')) { $this->bootRoutes(); } } @@ -95,7 +99,7 @@ protected function mergeConfigs() */ protected function setIsWebsocket() { - $this->isWebsocket = $this->app['config']->get('swoole_http.websocket.enabled'); + $this->isWebsocket = $this->app->make(Service::CONFIG_ALIAS)->get('swoole_http.websocket.enabled'); } /** @@ -114,11 +118,13 @@ protected function registerCommands() protected function createSwooleServer() { $server = $this->isWebsocket ? WebsocketServer::class : HttpServer::class; - $host = $this->app['config']->get('swoole_http.server.host'); - $port = $this->app['config']->get('swoole_http.server.port'); - $socketType = $this->app['config']->get('swoole_http.server.socket_type', SWOOLE_SOCK_TCP); + $config = $this->app->make(Service::CONFIG_ALIAS); + $host = $config->get('swoole_http.server.host'); + $port = $config->get('swoole_http.server.port'); + $socketType = $config->get('swoole_http.server.socket_type', SWOOLE_SOCK_TCP); + $processType = $config->get('swoole.http.server.process_type', SWOOLE_PROCESS); - static::$server = new $server($host, $port, SWOOLE_PROCESS, $socketType); + static::$server = new $server($host, $port, $processType, $socketType); } /** @@ -126,11 +132,11 @@ protected function createSwooleServer() */ protected function configureSwooleServer() { - $config = $this->app['config']; + $config = $this->app->make(Service::CONFIG_ALIAS); $options = $config->get('swoole_http.server.options'); // only enable task worker in websocket mode and for queue driver - if ($config->get('queue.default') !== 'swoole' && ! $this->isWebsocket) { + if ($config->get('queue.default') !== 'swoole' && !$this->isWebsocket) { unset($config['task_worker_num']); } @@ -149,9 +155,10 @@ protected function registerServer() $this->createSwooleServer(); $this->configureSwooleServer(); } + return static::$server; }); - $this->app->alias(Server::class, 'swoole.server'); + $this->app->alias(Server::class, Service::SERVER_ALIAS); } /** @@ -159,29 +166,69 @@ protected function registerServer() */ protected function registerDatabaseDriver() { - $this->app->resolving('db', function ($db) { + $this->app->extend('db', function ($db) { $db->extend('mysql-coroutine', function ($config, $name) { $config['name'] = $name; - $connection = function () use ($config) { - return (new MySqlConnector())->connect($config); - }; + $config = $this->getMergedDatabaseConfig($config, $name); - return new MySqlConnection( - $connection, + $connection = new MySqlConnection( + $this->getNewMySqlConnection($config), $config['database'], $config['prefix'], $config ); + + if (isset($config['read'])) { + $connection->setReadPdo($this->getNewMySqlConnection($config)); + } + + return $connection; }); + + return $db; }); } + /** + * Get mereged config for coroutine mysql. + * + * @param array $config + * @param string $name + * + * @return array + */ + protected function getMergedDatabaseConfig(array $config, string $name) + { + $config['name'] = $name; + + if (isset($config['read'])) { + $config = array_merge($config, $config['read']); + } + if (isset($config['write'])) { + $config = array_merge($config, $config['write']); + } + + return $config; + } + + /** + * Get a new mysql connection. + * + * @param array $config + * + * @return \PDO + */ + protected function getNewMySqlConnection(array $config) + { + return ConnectorFactory::make(FW::version())->connect($config); + } + /** * Register queue driver for swoole async task. */ protected function registerSwooleQueueDriver() { - $this->app->afterResolving('queue', function ($manager) { + $this->app->afterResolving('queue', function (Manager $manager) { $manager->addConnector('swoole', function () { return new SwooleTaskConnector($this->app->make(Server::class)); }); diff --git a/src/LaravelServiceProvider.php b/src/LaravelServiceProvider.php index 5cf86a30..fe35a3ce 100644 --- a/src/LaravelServiceProvider.php +++ b/src/LaravelServiceProvider.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http; + use SwooleTW\Http\Server\Manager; /** @@ -28,6 +29,6 @@ protected function registerManager() */ protected function bootRoutes() { - require __DIR__.'/../routes/laravel_routes.php'; + require __DIR__ . '/../routes/laravel_routes.php'; } } diff --git a/src/LumenServiceProvider.php b/src/LumenServiceProvider.php index f7ae8414..8e1bdfa9 100644 --- a/src/LumenServiceProvider.php +++ b/src/LumenServiceProvider.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http; + use SwooleTW\Http\Server\Manager; /** diff --git a/src/Server/Facades/Sandbox.php b/src/Server/Facades/Sandbox.php index 8c468254..6375ecbb 100644 --- a/src/Server/Facades/Sandbox.php +++ b/src/Server/Facades/Sandbox.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http\Server\Facades; + use Illuminate\Support\Facades\Facade; class Sandbox extends Facade diff --git a/src/Server/Facades/Server.php b/src/Server/Facades/Server.php index 7a34102a..8fc3e2b3 100644 --- a/src/Server/Facades/Server.php +++ b/src/Server/Facades/Server.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http\Server\Facades; + use Illuminate\Support\Facades\Facade; class Server extends Facade diff --git a/src/Server/Manager.php b/src/Server/Manager.php index b5715d81..695362b6 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -2,20 +2,26 @@ namespace SwooleTW\Http\Server; -use Throwable; -use Swoole\Http\Server; -use SwooleTW\Http\Server\Sandbox; -use SwooleTW\Http\Task\SwooleTaskJob; -use Illuminate\Support\Facades\Facade; -use SwooleTW\Http\Websocket\Websocket; -use SwooleTW\Http\Transformers\Request; -use SwooleTW\Http\Transformers\Response; -use SwooleTW\Http\Concerns\WithApplication; + +use Exception; use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Debug\ExceptionHandler; -use SwooleTW\Http\Concerns\InteractsWithWebsocket; +use Illuminate\Support\Facades\Facade; +use Illuminate\Support\Str; use SwooleTW\Http\Concerns\InteractsWithSwooleTable; +use SwooleTW\Http\Concerns\InteractsWithWebsocket; +use SwooleTW\Http\Concerns\WithApplication; +use SwooleTW\Http\Helpers\OS; +use SwooleTW\Http\Task\SwooleTaskJob; +use SwooleTW\Http\Transformers\Request; +use SwooleTW\Http\Transformers\Response; +use SwooleTW\Http\Websocket\Websocket; +use Symfony\Component\Debug\Exception\FatalThrowableError; +use Throwable; +/** + * Class Manager + */ class Manager { use InteractsWithWebsocket, @@ -53,10 +59,11 @@ class Manager /** * HTTP server manager constructor. * - * @param \Swoole\Http\Server $server * @param \Illuminate\Contracts\Container\Container $container * @param string $framework * @param string $basePath + * + * @throws \Exception */ public function __construct(Container $container, $framework, $basePath = null) { @@ -71,7 +78,7 @@ public function __construct(Container $container, $framework, $basePath = null) */ public function run() { - $this->container['swoole.server']->start(); + $this->container->make('swoole.server')->start(); } /** @@ -79,7 +86,7 @@ public function run() */ public function stop() { - $this->container['swoole.server']->shutdown(); + $this->container->make('swoole.server')->shutdown(); } /** @@ -98,17 +105,12 @@ protected function initialize() protected function setSwooleServerListeners() { foreach ($this->events as $event) { - $listener = 'on' . ucfirst($event); + $listener = Str::camel("on_$event"); + $callback = method_exists($this, $listener) ? [$this, $listener] : function () use ($event) { + $this->container->make('events')->fire("swoole.$event", func_get_args()); + }; - if (method_exists($this, $listener)) { - $this->container['swoole.server']->on($event, [$this, $listener]); - } else { - $this->container['swoole.server']->on($event, function () use ($event) { - $event = sprintf('swoole.%s', $event); - - $this->container['events']->fire($event, func_get_args()); - }); - } + $this->container->make('swoole.server')->on($event, $callback); } } @@ -120,7 +122,7 @@ public function onStart() $this->setProcessName('master process'); $this->createPidFile(); - $this->container['events']->fire('swoole.start', func_get_args()); + $this->container->make('events')->fire('swoole.start', func_get_args()); } /** @@ -131,23 +133,29 @@ public function onStart() public function onManagerStart() { $this->setProcessName('manager process'); - $this->container['events']->fire('swoole.managerStart', func_get_args()); + $this->container->make('events')->fire('swoole.managerStart', func_get_args()); } /** * "onWorkerStart" listener. + * + * @param \Swoole\Http\Server|mixed $server + * + * @throws \Exception */ public function onWorkerStart($server) { $this->clearCache(); - $this->setProcessName('worker process'); - $this->container['events']->fire('swoole.workerStart', func_get_args()); + $this->container->make('events')->fire('swoole.workerStart', func_get_args()); // don't init laravel app in task workers if ($server->taskworker) { + $this->setProcessName('task process'); + return; } + $this->setProcessName('worker process'); // clear events instance in case of repeated listeners in worker process Facade::clearResolvedInstance('events'); @@ -159,7 +167,7 @@ public function onWorkerStart($server) $this->bindToLaravelApp(); // prepare websocket handler and routes - if ($this->isWebsocket) { + if ($this->isServerWebsocket) { $this->prepareWebsocketHandler(); $this->loadWebsocketRoutes(); } @@ -173,11 +181,11 @@ public function onWorkerStart($server) */ public function onRequest($swooleRequest, $swooleResponse) { - $this->app['events']->fire('swoole.request'); + $this->app->make('events')->fire('swoole.request'); $this->resetOnRequest(); - $handleStatic = $this->container['config']->get('swoole_http.handle_static_files', true); - $publicPath = $this->container['config']->get('swoole_http.server.public_path', base_path('public')); + $handleStatic = $this->container->make('config')->get('swoole_http.handle_static_files', true); + $publicPath = $this->container->make('config')->get('swoole_http.server.public_path', base_path('public')); try { // handle static file request first @@ -188,17 +196,17 @@ public function onRequest($swooleRequest, $swooleResponse) $illuminateRequest = Request::make($swooleRequest)->toIlluminate(); // set current request to sandbox - $this->app['swoole.sandbox']->setRequest($illuminateRequest); + $this->app->make('swoole.sandbox')->setRequest($illuminateRequest); // enable sandbox - $this->app['swoole.sandbox']->enable(); + $this->app->make('swoole.sandbox')->enable(); // handle request via laravel/lumen's dispatcher - $illuminateResponse = $this->app['swoole.sandbox']->run($illuminateRequest); + $illuminateResponse = $this->app->make('swoole.sandbox')->run($illuminateRequest); $response = Response::make($illuminateResponse, $swooleResponse); $response->send(); } catch (Throwable $e) { try { - $exceptionResponse = $this->app[ExceptionHandler::class]->render($illuminateRequest, $e); + $exceptionResponse = $this->app->make(ExceptionHandler::class)->render(null, $e); $response = Response::make($exceptionResponse, $swooleResponse); $response->send(); } catch (Throwable $e) { @@ -206,7 +214,7 @@ public function onRequest($swooleRequest, $swooleResponse) } } finally { // disable and recycle sandbox resource - $this->app['swoole.sandbox']->disable(); + $this->app->make('swoole.sandbox')->disable(); } } @@ -216,31 +224,36 @@ public function onRequest($swooleRequest, $swooleResponse) protected function resetOnRequest() { // Reset websocket data - if ($this->isWebsocket) { - $this->app['swoole.websocket']->reset(true); + if ($this->isServerWebsocket) { + $this->app->make('swoole.websocket')->reset(true); } } /** * Set onTask listener. + * + * @param mixed $server + * @param string $taskId + * @param string $srcWorkerId + * @param mixed $data */ public function onTask($server, $taskId, $srcWorkerId, $data) { - $this->container['events']->fire('swoole.task', func_get_args()); + $this->container->make('events')->fire('swoole.task', func_get_args()); try { // push websocket message if (is_array($data)) { - if ($this->isWebsocket + if ($this->isServerWebsocket && array_key_exists('action', $data) && $data['action'] === Websocket::PUSH_ACTION) { $this->pushMessage($server, $data['data'] ?? []); } - // push async task to queue - } elseif (is_string($data)) { - $decoded = json_decode($data, true); + // push async task to queue + } else if (is_string($data)) { + $decoded = \json_decode($data, true); - if (JSON_ERROR_NONE === json_last_error() && isset($decoded['job'])) { + if (JSON_ERROR_NONE === \json_last_error() && isset($decoded['job'])) { (new SwooleTaskJob($this->container, $server, $data, $taskId, $srcWorkerId))->fire(); } } @@ -251,10 +264,16 @@ public function onTask($server, $taskId, $srcWorkerId, $data) /** * Set onFinish listener. + * + * @param mixed $server + * @param string $taskId + * @param mixed $data */ public function onFinish($server, $taskId, $data) { // task worker callback + $this->container->make('events')->fire('swoole.finish', func_get_args()); + return; } @@ -274,7 +293,7 @@ protected function bindToLaravelApp() $this->bindSandbox(); $this->bindSwooleTable(); - if ($this->isWebsocket) { + if ($this->isServerWebsocket) { $this->bindRoom(); $this->bindWebsocket(); } @@ -288,6 +307,7 @@ protected function bindSandbox() $this->app->singleton(Sandbox::class, function ($app) { return new Sandbox($app, $this->framework); }); + $this->app->alias(Sandbox::class, 'swoole.sandbox'); } @@ -298,7 +318,7 @@ protected function bindSandbox() */ protected function getPidFile() { - return $this->container['config']->get('swoole_http.server.options.pid_file'); + return $this->container->make('config')->get('swoole_http.server.options.pid_file'); } /** @@ -329,11 +349,11 @@ protected function removePidFile() */ protected function clearCache() { - if (function_exists('apc_clear_cache')) { + if (extension_loaded('apc')) { apc_clear_cache(); } - if (function_exists('opcache_reset')) { + if (extension_loaded('Zend OPcache')) { opcache_reset(); } } @@ -342,32 +362,23 @@ protected function clearCache() * Set process name. * * @codeCoverageIgnore + * * @param $process */ protected function setProcessName($process) { // MacOS doesn't support modifying process name. - if ($this->isMacOS() || $this->isInTesting()) { + if (OS::is(OS::MAC_OS) || $this->isInTesting()) { return; } $serverName = 'swoole_http_server'; - $appName = $this->container['config']->get('app.name', 'Laravel'); + $appName = $this->container->make('config')->get('app.name', 'Laravel'); $name = sprintf('%s: %s for %s', $serverName, $process, $appName); swoole_set_process_name($name); } - /** - * Indicates if the process is running in macOS. - * - * @return bool - */ - protected function isMacOS() - { - return PHP_OS === 'Darwin'; - } - /** * Indicates if it's in phpunit environment. * @@ -381,10 +392,14 @@ protected function isInTesting() /** * Log server error. * - * @param Throwable + * @param \Throwable|\Exception $e */ public function logServerError(Throwable $e) { - $this->container[ExceptionHandler::class]->report($e); + if (!$e instanceof Exception) { + $e = new FatalThrowableError($e); + } + + $this->container->make(ExceptionHandler::class)->report($e); } } diff --git a/src/Server/Resetters/BindRequest.php b/src/Server/Resetters/BindRequest.php index 35df56ce..610329c9 100644 --- a/src/Server/Resetters/BindRequest.php +++ b/src/Server/Resetters/BindRequest.php @@ -2,11 +2,14 @@ namespace SwooleTW\Http\Server\Resetters; + +use Illuminate\Contracts\Container\Container; use Illuminate\Http\Request; use SwooleTW\Http\Server\Sandbox; -use Illuminate\Contracts\Container\Container; -use SwooleTW\Http\Server\Resetters\ResetterContract; +/** + * Class BindRequest + */ class BindRequest implements ResetterContract { /** @@ -14,6 +17,8 @@ class BindRequest implements ResetterContract * * @param \Illuminate\Contracts\Container\Container $app * @param \SwooleTW\Http\Server\Sandbox $sandbox + * + * @return \Illuminate\Contracts\Container\Container */ public function handle(Container $app, Sandbox $sandbox) { diff --git a/src/Server/Resetters/ClearInstances.php b/src/Server/Resetters/ClearInstances.php index 24fc6963..9d0d446c 100644 --- a/src/Server/Resetters/ClearInstances.php +++ b/src/Server/Resetters/ClearInstances.php @@ -2,9 +2,9 @@ namespace SwooleTW\Http\Server\Resetters; -use SwooleTW\Http\Server\Sandbox; + use Illuminate\Contracts\Container\Container; -use SwooleTW\Http\Server\Resetters\ResetterContract; +use SwooleTW\Http\Server\Sandbox; class ClearInstances implements ResetterContract { @@ -13,6 +13,8 @@ class ClearInstances implements ResetterContract * * @param \Illuminate\Contracts\Container\Container $app * @param \SwooleTW\Http\Server\Sandbox $sandbox + * + * @return \Illuminate\Contracts\Container\Container */ public function handle(Container $app, Sandbox $sandbox) { diff --git a/src/Server/Resetters/RebindKernelContainer.php b/src/Server/Resetters/RebindKernelContainer.php index f97a07ac..7a8187be 100644 --- a/src/Server/Resetters/RebindKernelContainer.php +++ b/src/Server/Resetters/RebindKernelContainer.php @@ -2,18 +2,25 @@ namespace SwooleTW\Http\Server\Resetters; -use SwooleTW\Http\Server\Sandbox; -use Illuminate\Contracts\Http\Kernel; + use Illuminate\Contracts\Container\Container; -use SwooleTW\Http\Server\Resetters\ResetterContract; +use Illuminate\Contracts\Http\Kernel; +use SwooleTW\Http\Server\Sandbox; class RebindKernelContainer implements ResetterContract { + /** + * @var \Illuminate\Contracts\Container\Container + */ + protected $app; + /** * "handle" function for resetting app. * * @param \Illuminate\Contracts\Container\Container $app * @param \SwooleTW\Http\Server\Sandbox $sandbox + * + * @return \Illuminate\Contracts\Container\Container */ public function handle(Container $app, Sandbox $sandbox) { diff --git a/src/Server/Resetters/RebindRouterContainer.php b/src/Server/Resetters/RebindRouterContainer.php index c51398ce..ca6151ed 100644 --- a/src/Server/Resetters/RebindRouterContainer.php +++ b/src/Server/Resetters/RebindRouterContainer.php @@ -2,18 +2,30 @@ namespace SwooleTW\Http\Server\Resetters; -use SwooleTW\Http\Server\Sandbox; + use Illuminate\Contracts\Container\Container; -use SwooleTW\Http\Server\Resetters\ResetterContract; +use SwooleTW\Http\Server\Sandbox; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class RebindRouterContainer implements ResetterContract { + /** + * @var \Illuminate\Contracts\Container\Container + */ + protected $container; + + /** + * @var mixed + */ + protected $routes; + /** * "handle" function for resetting app. * * @param \Illuminate\Contracts\Container\Container $app * @param \SwooleTW\Http\Server\Sandbox $sandbox + * + * @return \Illuminate\Contracts\Container\Container */ public function handle(Container $app, Sandbox $sandbox) { @@ -26,6 +38,7 @@ public function handle(Container $app, Sandbox $sandbox) return; } try { + /** @var mixed $route */ $route = $this->routes->match($request); // clear resolved controller if (property_exists($route, 'container')) { diff --git a/src/Server/Resetters/RebindViewContainer.php b/src/Server/Resetters/RebindViewContainer.php index 52bd5ab1..3f1cb57f 100644 --- a/src/Server/Resetters/RebindViewContainer.php +++ b/src/Server/Resetters/RebindViewContainer.php @@ -2,17 +2,29 @@ namespace SwooleTW\Http\Server\Resetters; -use SwooleTW\Http\Server\Sandbox; + use Illuminate\Contracts\Container\Container; -use SwooleTW\Http\Server\Resetters\ResetterContract; +use SwooleTW\Http\Server\Sandbox; class RebindViewContainer implements ResetterContract { + /** + * @var Container + */ + protected $container; + + /** + * @var array + */ + protected $shared; + /** * "handle" function for resetting app. * * @param \Illuminate\Contracts\Container\Container $app * @param \SwooleTW\Http\Server\Sandbox $sandbox + * + * @return \Illuminate\Contracts\Container\Container */ public function handle(Container $app, Sandbox $sandbox) { diff --git a/src/Server/Resetters/ResetConfig.php b/src/Server/Resetters/ResetConfig.php index 5fbfd042..4a0356c8 100644 --- a/src/Server/Resetters/ResetConfig.php +++ b/src/Server/Resetters/ResetConfig.php @@ -2,9 +2,9 @@ namespace SwooleTW\Http\Server\Resetters; -use SwooleTW\Http\Server\Sandbox; + use Illuminate\Contracts\Container\Container; -use SwooleTW\Http\Server\Resetters\ResetterContract; +use SwooleTW\Http\Server\Sandbox; class ResetConfig implements ResetterContract { @@ -13,6 +13,8 @@ class ResetConfig implements ResetterContract * * @param \Illuminate\Contracts\Container\Container $app * @param \SwooleTW\Http\Server\Sandbox $sandbox + * + * @return \Illuminate\Contracts\Container\Container */ public function handle(Container $app, Sandbox $sandbox) { diff --git a/src/Server/Resetters/ResetCookie.php b/src/Server/Resetters/ResetCookie.php index c9b76da9..2d89cf44 100644 --- a/src/Server/Resetters/ResetCookie.php +++ b/src/Server/Resetters/ResetCookie.php @@ -2,9 +2,9 @@ namespace SwooleTW\Http\Server\Resetters; -use SwooleTW\Http\Server\Sandbox; + use Illuminate\Contracts\Container\Container; -use SwooleTW\Http\Server\Resetters\ResetterContract; +use SwooleTW\Http\Server\Sandbox; class ResetCookie implements ResetterContract { @@ -13,6 +13,8 @@ class ResetCookie implements ResetterContract * * @param \Illuminate\Contracts\Container\Container $app * @param \SwooleTW\Http\Server\Sandbox $sandbox + * + * @return \Illuminate\Contracts\Container\Container */ public function handle(Container $app, Sandbox $sandbox) { diff --git a/src/Server/Resetters/ResetProviders.php b/src/Server/Resetters/ResetProviders.php index 0b11648e..f232f9d8 100644 --- a/src/Server/Resetters/ResetProviders.php +++ b/src/Server/Resetters/ResetProviders.php @@ -2,17 +2,24 @@ namespace SwooleTW\Http\Server\Resetters; -use SwooleTW\Http\Server\Sandbox; + use Illuminate\Contracts\Container\Container; -use SwooleTW\Http\Server\Resetters\ResetterContract; +use SwooleTW\Http\Server\Sandbox; class ResetProviders implements ResetterContract { + /** + * @var \Illuminate\Contracts\Container\Container + */ + protected $app; + /** * "handle" function for resetting app. * * @param \Illuminate\Contracts\Container\Container $app * @param \SwooleTW\Http\Server\Sandbox $sandbox + * + * @return \Illuminate\Contracts\Container\Container */ public function handle(Container $app, Sandbox $sandbox) { @@ -31,6 +38,9 @@ public function handle(Container $app, Sandbox $sandbox) /** * Rebind service provider's container. + * + * @param $app + * @param $provider */ protected function rebindProviderContainer($app, $provider) { diff --git a/src/Server/Resetters/ResetSession.php b/src/Server/Resetters/ResetSession.php index 84db650c..3848d55d 100644 --- a/src/Server/Resetters/ResetSession.php +++ b/src/Server/Resetters/ResetSession.php @@ -2,9 +2,9 @@ namespace SwooleTW\Http\Server\Resetters; -use SwooleTW\Http\Server\Sandbox; + use Illuminate\Contracts\Container\Container; -use SwooleTW\Http\Server\Resetters\ResetterContract; +use SwooleTW\Http\Server\Sandbox; class ResetSession implements ResetterContract { @@ -13,6 +13,8 @@ class ResetSession implements ResetterContract * * @param \Illuminate\Contracts\Container\Container $app * @param \SwooleTW\Http\Server\Sandbox $sandbox + * + * @return \Illuminate\Contracts\Container\Container */ public function handle(Container $app, Sandbox $sandbox) { diff --git a/src/Server/Resetters/ResetterContract.php b/src/Server/Resetters/ResetterContract.php index 5f63611f..e6398751 100644 --- a/src/Server/Resetters/ResetterContract.php +++ b/src/Server/Resetters/ResetterContract.php @@ -2,8 +2,9 @@ namespace SwooleTW\Http\Server\Resetters; -use SwooleTW\Http\Server\Sandbox; + use Illuminate\Contracts\Container\Container; +use SwooleTW\Http\Server\Sandbox; interface ResetterContract { diff --git a/src/Server/Sandbox.php b/src/Server/Sandbox.php index 0dbf367f..8c6059ce 100644 --- a/src/Server/Sandbox.php +++ b/src/Server/Sandbox.php @@ -2,25 +2,30 @@ namespace SwooleTW\Http\Server; -use Illuminate\Http\Request; -use Illuminate\Container\Container; -use SwooleTW\Http\Coroutine\Context; + +use Illuminate\Container\Container as ContainerFacade; +use Illuminate\Contracts\Config\Repository as ConfigContract; +use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Http\Kernel; +use Illuminate\Http\Request; use Illuminate\Support\Facades\Facade; +use Laravel\Lumen\Application as LumenApplication; use SwooleTW\Http\Concerns\ResetApplication; +use SwooleTW\Http\Coroutine\Context; use SwooleTW\Http\Exceptions\SandboxException; -use Laravel\Lumen\Application as LumenApplication; -use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpFoundation\BinaryFileResponse; -use Illuminate\Contracts\Config\Repository as ConfigContract; use Symfony\Component\HttpFoundation\Response as SymfonyResponse; +use Symfony\Component\HttpFoundation\StreamedResponse; +/** + * Class Sandbox + */ class Sandbox { use ResetApplication; /** - * @var \Illuminate\Container\Container + * @var \Illuminate\Contracts\Container\Container */ protected $app; @@ -31,10 +36,15 @@ class Sandbox /** * Constructor + * + * @param null $app + * @param null $framework + * + * @throws \SwooleTW\Http\Exceptions\SandboxException */ public function __construct($app = null, $framework = null) { - if (! $app instanceof Container) { + if (!$app instanceof Container) { return; } @@ -45,6 +55,10 @@ public function __construct($app = null, $framework = null) /** * Set framework type. + * + * @param string $framework + * + * @return \SwooleTW\Http\Server\Sandbox */ public function setFramework(string $framework) { @@ -64,7 +78,9 @@ public function getFramework() /** * Set a base application. * - * @param \Illuminate\Container\Container + * @param \Illuminate\Contracts\Container\Container $app + * + * @return \SwooleTW\Http\Server\Sandbox */ public function setBaseApp(Container $app) { @@ -77,6 +93,8 @@ public function setBaseApp(Container $app) * Set current request. * * @param \Illuminate\Http\Request + * + * @return \SwooleTW\Http\Server\Sandbox */ public function setRequest(Request $request) { @@ -88,7 +106,9 @@ public function setRequest(Request $request) /** * Set current snapshot. * - * @param \Illuminate\Container\Container + * @param \Illuminate\Contracts\Container\Container $snapshot + * + * @return \SwooleTW\Http\Server\Sandbox */ public function setSnapshot(Container $snapshot) { @@ -99,10 +119,12 @@ public function setSnapshot(Container $snapshot) /** * Initialize based on base app. + * + * @throws \SwooleTW\Http\Exceptions\SandboxException */ public function initialize() { - if (! $this->app instanceof Container) { + if (!$this->app instanceof Container) { throw new SandboxException('A base app has not been set.'); } @@ -116,7 +138,7 @@ public function initialize() /** * Get base application. * - * @return \Illuminate\Container\Container + * @return \Illuminate\Contracts\Container\Container */ public function getBaseApp() { @@ -126,12 +148,12 @@ public function getBaseApp() /** * Get an application snapshot * - * @return \Illuminate\Container\Container + * @return \Illuminate\Contracts\Container\Container|mixed */ public function getApplication() { $snapshot = $this->getSnapshot(); - if ($snapshot instanceOf Container) { + if ($snapshot instanceof Container) { return $snapshot; } @@ -145,11 +167,14 @@ public function getApplication() * Run framework. * * @param \Illuminate\Http\Request $request + * * @return \Illuminate\Http\Response + * @throws \SwooleTW\Http\Exceptions\SandboxException + * @throws \ReflectionException */ public function run(Request $request) { - if (! $this->getSnapshot() instanceof Container) { + if (!$this->getSnapshot() instanceof Container) { throw new SandboxException('Sandbox is not enabled.'); } @@ -166,7 +191,9 @@ public function run(Request $request) * Handle request for non-ob case. * * @param \Illuminate\Http\Request $request + * * @return \Illuminate\Http\Response + * @throws \ReflectionException */ protected function prepareResponse(Request $request) { @@ -183,7 +210,9 @@ protected function prepareResponse(Request $request) * Handle request for ob output. * * @param \Illuminate\Http\Request $request + * * @return \Illuminate\Http\Response + * @throws \ReflectionException */ protected function prepareObResponse(Request $request) { @@ -197,18 +226,19 @@ protected function prepareObResponse(Request $request) $isFile = false; if ($isStream = $response instanceof StreamedResponse) { $response->sendContent(); - } elseif ($response instanceof SymfonyResponse) { + } else if ($response instanceof SymfonyResponse) { $content = $response->getContent(); - } elseif (! $isFile = $response instanceof BinaryFileResponse) { - $content = (string) $response; + } else if (!$isFile = $response instanceof BinaryFileResponse) { + $content = (string)$response; } // process terminating logics $this->terminate($request, $response); // append ob content to response - if (! $isFile && ob_get_length() > 0) { + if (!$isFile && ob_get_length() > 0) { if ($isStream) { + // TODO add output to StreamedResponse to avoid 'Field declared dynamically' $response->output = ob_get_contents(); } else { $response->setContent(ob_get_contents() . $content); @@ -224,6 +254,7 @@ protected function prepareObResponse(Request $request) * Handle request through Laravel or Lumen. * * @param \Illuminate\Http\Request $request + * * @return \Illuminate\Http\Response */ protected function handleRequest(Request $request) @@ -254,6 +285,8 @@ public function isLaravel() /** * @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Response $response + * + * @throws \ReflectionException */ public function terminate(Request $request, $response) { @@ -277,10 +310,12 @@ public function terminate(Request $request, $response) /** * Set laravel snapshot to container and facade. + * + * @throws \SwooleTW\Http\Exceptions\SandboxException */ public function enable() { - if (! $this->config instanceof ConfigContract) { + if (!$this->config instanceof ConfigContract) { throw new SandboxException('Please initialize after setting base app.'); } @@ -299,6 +334,8 @@ public function disable() /** * Replace app's self bindings. + * + * @param \Illuminate\Contracts\Container\Container|mixed $app */ public function setInstance(Container $app) { @@ -309,7 +346,7 @@ public function setInstance(Container $app) $app->instance(LumenApplication::class, $app); } - Container::setInstance($app); + ContainerFacade::setInstance($app); Context::setApp($app); Facade::clearResolvedInstances(); Facade::setFacadeApplication($app); @@ -328,7 +365,7 @@ public function getSnapshot() */ protected function removeRequest() { - return Context::removeData('_request'); + Context::removeData('_request'); } /** diff --git a/src/Server/helpers.php b/src/Server/helpers.php index 7fb15785..624043bc 100644 --- a/src/Server/helpers.php +++ b/src/Server/helpers.php @@ -3,16 +3,20 @@ /** * This is only for `function not exists` in config/swoole_http.php. */ -if (! function_exists('swoole_cpu_num')) { - function swoole_cpu_num() +if (!function_exists('swoole_cpu_num')) { + function swoole_cpu_num(): int { - return; + return 1; } } /** * This is only for `function not exists` in config/swoole_http.php. */ -if (! defined('SWOOLE_SOCK_TCP')) { +if (!defined('SWOOLE_SOCK_TCP')) { define('SWOOLE_SOCK_TCP', 1); } + +if (!defined('SWOOLE_PROCESS')) { + define('SWOOLE_PROCESS', 3); +} diff --git a/src/Table/Facades/SwooleTable.php b/src/Table/Facades/SwooleTable.php index f5441690..fb89a85b 100644 --- a/src/Table/Facades/SwooleTable.php +++ b/src/Table/Facades/SwooleTable.php @@ -2,8 +2,12 @@ namespace SwooleTW\Http\Table\Facades; + use Illuminate\Support\Facades\Facade; +/** + * Class SwooleTable + */ class SwooleTable extends Facade { /** diff --git a/src/Table/SwooleTable.php b/src/Table/SwooleTable.php index 9dfe8947..be046f30 100644 --- a/src/Table/SwooleTable.php +++ b/src/Table/SwooleTable.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http\Table; + use Swoole\Table; class SwooleTable @@ -18,6 +19,7 @@ class SwooleTable * * @param string $name * @param \Swoole\Table $table + * * @return \SwooleTW\Http\Table\SwooleTable */ public function add(string $name, Table $table) @@ -31,6 +33,7 @@ public function add(string $name, Table $table) * Get a swoole table by its name from existing tables. * * @param string $name + * * @return \Swoole\Table $table */ public function get(string $name) @@ -51,7 +54,8 @@ public function getAll() /** * Dynamically access table. * - * @param string $key + * @param string $key + * * @return table */ public function __get($key) diff --git a/src/Task/Connectors/SwooleTaskConnector.php b/src/Task/Connectors/SwooleTaskConnector.php index 3b690aac..0ab71f3a 100644 --- a/src/Task/Connectors/SwooleTaskConnector.php +++ b/src/Task/Connectors/SwooleTaskConnector.php @@ -2,9 +2,14 @@ namespace SwooleTW\Http\Task\Connectors; -use SwooleTW\Http\Task\SwooleTaskQueue; + use Illuminate\Queue\Connectors\ConnectorInterface; +use SwooleTW\Http\Helpers\FW; +use SwooleTW\Http\Task\QueueFactory; +/** + * Class SwooleTaskConnector + */ class SwooleTaskConnector implements ConnectorInterface { /** @@ -14,10 +19,11 @@ class SwooleTaskConnector implements ConnectorInterface */ protected $swoole; - /** + /** * Create a new Swoole Async task connector instance. * * @param \Swoole\Http\Server $swoole + * * @return void */ public function __construct($swoole) @@ -28,11 +34,12 @@ public function __construct($swoole) /** * Establish a queue connection. * - * @param array $config + * @param array $config + * * @return \Illuminate\Contracts\Queue\Queue */ public function connect(array $config) { - return new SwooleTaskQueue($this->swoole); + return QueueFactory::make($this->swoole, FW::version()); } } diff --git a/src/Task/QueueFactory.php b/src/Task/QueueFactory.php new file mode 100644 index 00000000..a9d8bb9a --- /dev/null +++ b/src/Task/QueueFactory.php @@ -0,0 +1,108 @@ +getDocComment(), $result)) { + $fileVersion = Arr::first($result); + } + } + + return version_compare($fileVersion, $version, '>='); + } catch (\Exception $e) { + return false; + } + } + + /** + * @param string $version + * + * @return bool + */ + protected static function hasBreakingChanges(string $version): bool + { + return version_compare($version, self::CHANGE_VERSION, '>='); + } +} diff --git a/src/Task/SwooleTaskJob.php b/src/Task/SwooleTaskJob.php index 5a70b7a9..701c2b55 100644 --- a/src/Task/SwooleTaskJob.php +++ b/src/Task/SwooleTaskJob.php @@ -2,10 +2,14 @@ namespace SwooleTW\Http\Task; -use Illuminate\Queue\Jobs\Job; + use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Queue\Job as JobContract; +use Illuminate\Queue\Jobs\Job; +/** + * Class SwooleTaskJob + */ class SwooleTaskJob extends Job implements JobContract { /** @@ -36,15 +40,19 @@ class SwooleTaskJob extends Job implements JobContract */ protected $srcWrokerId; + /** + * @var int + */ + protected $srcWorkderId; + /** * Create a new job instance. * - * @param \Illuminate\Container\Container $container - * @param \Swoole\Http\Server $swoole - * @param string $job - * @param int $taskId - * @param int $srcWorkerId - * @return void + * @param \Illuminate\Contracts\Container\Container $container + * @param \Swoole\Http\Server $swoole + * @param string $job + * @param int $taskId + * @param $srcWrokerId */ public function __construct(Container $container, $swoole, $job, $taskId, $srcWrokerId) { @@ -63,7 +71,7 @@ public function __construct(Container $container, $swoole, $job, $taskId, $srcWr public function fire() { if (method_exists($this, 'resolveAndFire')) { - $this->resolveAndFire(json_decode($this->getRawBody(), true)); + $this->resolveAndFire(\json_decode($this->getRawBody(), true)); } else { parent::fire(); } @@ -71,6 +79,7 @@ public function fire() /** * Get the number of times the job has been attempted. + * * @return int */ public function attempts() @@ -80,6 +89,7 @@ public function attempts() /** * Get the raw body string for the job. + * * @return string */ public function getRawBody() @@ -87,9 +97,9 @@ public function getRawBody() return $this->job; } - /** * Get the job identifier. + * * @return string */ public function getJobId() @@ -100,7 +110,7 @@ public function getJobId() /** * Get the service container instance. * - * @return \Illuminate\Container\Container + * @return \Illuminate\Contracts\Container\Container */ public function getContainer() { diff --git a/src/Task/SwooleTaskQueue.php b/src/Task/SwooleTaskQueue.php index 734fbc4a..0a28fedf 100644 --- a/src/Task/SwooleTaskQueue.php +++ b/src/Task/SwooleTaskQueue.php @@ -2,11 +2,15 @@ namespace SwooleTW\Http\Task; + use Exception; -use Swoole\Timer; -use Illuminate\Queue\Queue; use Illuminate\Contracts\Queue\Queue as QueueContract; +use Illuminate\Queue\Queue; +use Swoole\Timer; +/** + * Class SwooleTaskQueue (5.7) + */ class SwooleTaskQueue extends Queue implements QueueContract { /** @@ -19,7 +23,7 @@ class SwooleTaskQueue extends Queue implements QueueContract /** * Create Async Task instance. * - * @param \Swoole\Http\Server $swoole + * @param \Swoole\Http\Server $swoole */ public function __construct($swoole) { @@ -29,9 +33,10 @@ public function __construct($swoole) /** * Push a new job onto the queue. * - * @param string|object $job - * @param mixed $data - * @param string $queue + * @param string|object $job + * @param mixed $data + * @param string $queue + * * @return mixed */ public function push($job, $data = '', $queue = null) @@ -42,23 +47,25 @@ public function push($job, $data = '', $queue = null) /** * Push a raw payload onto the queue. * - * @param string $payload - * @param string $queue - * @param array $options + * @param string $payload + * @param string $queue + * @param array $options + * * @return mixed */ public function pushRaw($payload, $queue = null, array $options = []) { - return $this->swoole->task($payload, ! is_numeric($queue) ? 1 : (int) $queue); + return $this->swoole->task($payload, !is_numeric($queue) ? 1 : (int)$queue); } /** * Push a new job onto the queue after a delay. * - * @param \DateTimeInterface|\DateInterval|int $delay - * @param string|object $job - * @param mixed $data - * @param string $queue + * @param \DateTimeInterface|\DateInterval|int $delay + * @param string|object $job + * @param mixed $data + * @param string $queue + * * @return mixed */ public function later($delay, $job, $data = '', $queue = null) @@ -71,12 +78,13 @@ public function later($delay, $job, $data = '', $queue = null) /** * Create a typical, string based queue payload array. * - * @param string $job - * @param mixed $data + * @param string $job + * @param string $queue + * @param mixed $data * - * @throws Expcetion + * @throws \Exception */ - protected function createStringPayload($job, $data) + protected function createStringPayload($job, $queue, $data) { throw new Exception('Unsupported empty data'); } @@ -84,7 +92,8 @@ protected function createStringPayload($job, $data) /** * Get the size of the queue. * - * @param string $queue + * @param string $queue + * * @return int */ public function size($queue = null) @@ -95,7 +104,8 @@ public function size($queue = null) /** * Pop the next job off of the queue. * - * @param string $queue + * @param string $queue + * * @return \Illuminate\Contracts\Queue\Job|null */ public function pop($queue = null) diff --git a/src/Transformers/Request.php b/src/Transformers/Request.php index 704ab911..c5777f2a 100644 --- a/src/Transformers/Request.php +++ b/src/Transformers/Request.php @@ -2,15 +2,18 @@ namespace SwooleTW\Http\Transformers; + use Illuminate\Http\Request as IlluminateRequest; use Swoole\Http\Request as SwooleRequest; -use Swoole\Http\Response as SwooleResponse; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request as SymfonyRequest; +/** + * Class Request + */ class Request { - const BLACK_LIST = ['php', 'htaccess', 'config']; + private const BLACK_LIST = ['php', 'htaccess', 'config']; /** * @var \Illuminate\Http\Request @@ -21,7 +24,8 @@ class Request * Make a request. * * @param \Swoole\Http\Request $swooleRequest - * @return \SwooleTW\Http\Server\Request + * + * @return \SwooleTW\Http\Transformers\Request */ public static function make(SwooleRequest $swooleRequest) { @@ -40,6 +44,7 @@ public static function make(SwooleRequest $swooleRequest) * @param array $files * @param array $server * @param string $content + * * @throws \LogicException */ public function __construct(array $get, array $post, array $cookie, array $files, array $server, $content = null) @@ -56,8 +61,8 @@ public function __construct(array $get, array $post, array $cookie, array $files * @param array $files * @param array $server * @param string $content - * @return \Illuminate\Http\Request - * @throws \LogicException + * + * @return void */ protected function createIlluminateRequest($get, $post, $cookie, $files, $server, $content = null) { @@ -86,7 +91,7 @@ protected function createIlluminateRequest($get, $post, $cookie, $files, $server $request = new SymfonyRequest($get, $post, [], $cookie, $files, $server, $content); if (0 === strpos($request->headers->get('CONTENT_TYPE'), 'application/x-www-form-urlencoded') - && in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), array('PUT', 'DELETE', 'PATCH')) + && in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), ['PUT', 'DELETE', 'PATCH']) ) { parse_str($request->getContent(), $data); $request->request = new ParameterBag($data); @@ -115,6 +120,7 @@ public function getIlluminateRequest() * Transforms request parameters. * * @param \Swoole\Http\Request $request + * * @return array */ protected static function toIlluminateParameters(SwooleRequest $request) @@ -136,6 +142,7 @@ protected static function toIlluminateParameters(SwooleRequest $request) * * @param array $server * @param array $header + * * @return array */ protected static function transformServerParameters(array $server, array $header) @@ -151,7 +158,7 @@ protected static function transformServerParameters(array $server, array $header $key = str_replace('-', '_', $key); $key = strtoupper($key); - if (! in_array($key, ['REMOTE_ADDR', 'SERVER_PORT', 'HTTPS'])) { + if (!in_array($key, ['REMOTE_ADDR', 'SERVER_PORT', 'HTTPS'])) { $key = 'HTTP_' . $key; } @@ -166,27 +173,28 @@ protected static function transformServerParameters(array $server, array $header * * @param \Swoole\Http\Request $swooleRequest * @param \Swoole\Http\Response $swooleResponse - * @param string $path - * @return boolean + * @param string $publicPath + * + * @return boolean|null */ public static function handleStatic($swooleRequest, $swooleResponse, string $publicPath) { $uri = $swooleRequest->server['request_uri'] ?? ''; $extension = substr(strrchr($uri, '.'), 1); if ($extension && in_array($extension, static::BLACK_LIST)) { - return; + return null; } $filename = $publicPath . $uri; - if (! is_file($filename) || filesize($filename) === 0) { - return; + if (!is_file($filename) || filesize($filename) === 0) { + return null; } $swooleResponse->status(200); $mime = mime_content_type($filename); if ($extension === 'js') { $mime = 'text/javascript'; - } elseif ($extension === 'css') { + } else if ($extension === 'css') { $mime = 'text/css'; } $swooleResponse->header('Content-Type', $mime); diff --git a/src/Transformers/Response.php b/src/Transformers/Response.php index 5efd0239..873e5508 100644 --- a/src/Transformers/Response.php +++ b/src/Transformers/Response.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http\Transformers; + use Illuminate\Http\Response as IlluminateResponse; use Swoole\Http\Response as SwooleResponse; use Symfony\Component\HttpFoundation\BinaryFileResponse; @@ -25,7 +26,8 @@ class Response * * @param $illuminateResponse * @param \Swoole\Http\Response $swooleResponse - * @return \SwooleTW\Http\Server\Response + * + * @return \SwooleTW\Http\Transformers\Response */ public static function make($illuminateResponse, SwooleResponse $swooleResponse) { @@ -65,7 +67,7 @@ protected function sendHeaders() $illuminateResponse = $this->getIlluminateResponse(); /* RFC2616 - 14.18 says all Responses need to have a Date */ - if (! $illuminateResponse->headers->has('Date')) { + if (!$illuminateResponse->headers->has('Date')) { $illuminateResponse->setDate(\DateTime::createFromFormat('U', time())); } @@ -103,11 +105,10 @@ protected function sendContent() { $illuminateResponse = $this->getIlluminateResponse(); - if ($illuminateResponse instanceof StreamedResponse && - property_exists($illuminateResponse, 'output') - ) { + if ($illuminateResponse instanceof StreamedResponse && property_exists($illuminateResponse, 'output')) { + // TODO Add Streamed Response with output $this->swooleResponse->end($illuminateResponse->output); - } elseif ($illuminateResponse instanceof BinaryFileResponse) { + } else if ($illuminateResponse instanceof BinaryFileResponse) { $this->swooleResponse->sendfile($illuminateResponse->getFile()->getPathname()); } else { $this->swooleResponse->end($illuminateResponse->getContent()); @@ -116,7 +117,8 @@ protected function sendContent() /** * @param \Swoole\Http\Response $swooleResponse - * @return \SwooleTW\Http\Server\Response + * + * @return \SwooleTW\Http\Transformers\Response */ protected function setSwooleResponse(SwooleResponse $swooleResponse) { @@ -135,12 +137,13 @@ public function getSwooleResponse() /** * @param mixed illuminateResponse - * @return \SwooleTW\Http\Server\Response + * + * @return \SwooleTW\Http\Transformers\Response */ protected function setIlluminateResponse($illuminateResponse) { - if (! $illuminateResponse instanceof SymfonyResponse) { - $content = (string) $illuminateResponse; + if (!$illuminateResponse instanceof SymfonyResponse) { + $content = (string)$illuminateResponse; $illuminateResponse = new IlluminateResponse($content); } diff --git a/src/Websocket/Authenticatable.php b/src/Websocket/Authenticatable.php index ae9d1c3d..b33dfcac 100644 --- a/src/Websocket/Authenticatable.php +++ b/src/Websocket/Authenticatable.php @@ -2,15 +2,25 @@ namespace SwooleTW\Http\Websocket; -use InvalidArgumentException; + use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; +use InvalidArgumentException; +/** + * Trait Authenticatable + * + * @property-read \SwooleTW\Http\Websocket\Rooms\RoomContract $room + */ trait Authenticatable { protected $userId; /** * Login using current user. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * + * @return mixed */ public function loginUsing(AuthenticatableContract $user) { @@ -19,6 +29,10 @@ public function loginUsing(AuthenticatableContract $user) /** * Login using current userId. + * + * @param $userId + * + * @return mixed */ public function loginUsingId($userId) { @@ -27,11 +41,13 @@ public function loginUsingId($userId) /** * Logout with current sender's fd. + * + * @return mixed */ public function logout() { if (is_null($userId = $this->getUserId())) { - return; + return null; } return $this->leave(static::USER_PREFIX . $userId); @@ -39,13 +55,18 @@ public function logout() /** * Set multiple recepients' fds by users. + * + * @param $users + * + * @return \SwooleTW\Http\Websocket\Authenticatable */ public function toUser($users) { $users = is_object($users) ? func_get_args() : $users; - $userIds = array_map(function ($user) { + $userIds = array_map(function (AuthenticatableContract $user) { $this->checkUser($user); + return $user->getAuthIdentifier(); }, $users); @@ -54,6 +75,10 @@ public function toUser($users) /** * Set multiple recepients' fds by userIds. + * + * @param $userIds + * + * @return \SwooleTW\Http\Websocket\Authenticatable */ public function toUserId($userIds) { @@ -72,7 +97,7 @@ public function toUserId($userIds) */ public function getUserId() { - if (! is_null($this->userId)) { + if (!is_null($this->userId)) { return $this->userId; } @@ -89,18 +114,24 @@ public function getUserId() /** * Check if a user is online by given userId. + * + * @param $userId + * + * @return bool */ public function isUserIdOnline($userId) { - return ! empty($this->room->getClients(static::USER_PREFIX . $userId)); + return !empty($this->room->getClients(static::USER_PREFIX . $userId)); } /** * Check if user object implements AuthenticatableContract. + * + * @param $user */ protected function checkUser($user) { - if (! $user instanceOf AuthenticatableContract) { + if (!$user instanceOf AuthenticatableContract) { throw new InvalidArgumentException('user object must implement ' . AuthenticatableContract::class); } } diff --git a/src/Websocket/Facades/Room.php b/src/Websocket/Facades/Room.php index e0a26fd4..e702b9c8 100644 --- a/src/Websocket/Facades/Room.php +++ b/src/Websocket/Facades/Room.php @@ -2,8 +2,12 @@ namespace SwooleTW\Http\Websocket\Facades; + use Illuminate\Support\Facades\Facade; +/** + * Class Room + */ class Room extends Facade { /** diff --git a/src/Websocket/Facades/Websocket.php b/src/Websocket/Facades/Websocket.php index 8c24866b..a7313000 100644 --- a/src/Websocket/Facades/Websocket.php +++ b/src/Websocket/Facades/Websocket.php @@ -2,8 +2,12 @@ namespace SwooleTW\Http\Websocket\Facades; + use Illuminate\Support\Facades\Facade; +/** + * Class Websocket + */ class Websocket extends Facade { /** diff --git a/src/Websocket/HandlerContract.php b/src/Websocket/HandlerContract.php index c664026f..658d5eea 100644 --- a/src/Websocket/HandlerContract.php +++ b/src/Websocket/HandlerContract.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http\Websocket; + use Illuminate\Http\Request; use Swoole\Websocket\Frame; diff --git a/src/Websocket/Middleware/Authenticate.php b/src/Websocket/Middleware/Authenticate.php index 27315d7b..3ca343dd 100644 --- a/src/Websocket/Middleware/Authenticate.php +++ b/src/Websocket/Middleware/Authenticate.php @@ -2,23 +2,28 @@ namespace SwooleTW\Http\Websocket\Middleware; + use Closure; use Illuminate\Auth\AuthenticationException; use Illuminate\Contracts\Auth\Factory as Auth; +/** + * Class Authenticate + */ class Authenticate { /** * The authentication factory instance. * - * @var \Illuminate\Contracts\Auth\Factory + * @var \Illuminate\Contracts\Auth\Factory|mixed */ protected $auth; /** * Create a new middleware instance. * - * @param \Illuminate\Contracts\Auth\Factory $auth + * @param \Illuminate\Contracts\Auth\Factory $auth + * * @return void */ public function __construct(Auth $auth) @@ -29,11 +34,11 @@ public function __construct(Auth $auth) /** * Handle an incoming request. * - * @param \Illuminate\Http\Request $request - * @param \Closure $next + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * * @return mixed * - * @throws \Illuminate\Auth\AuthenticationException */ public function handle($request, Closure $next) { diff --git a/src/Websocket/Middleware/DecryptCookies.php b/src/Websocket/Middleware/DecryptCookies.php index 6a76c65e..6d564944 100644 --- a/src/Websocket/Middleware/DecryptCookies.php +++ b/src/Websocket/Middleware/DecryptCookies.php @@ -2,12 +2,15 @@ namespace SwooleTW\Http\Websocket\Middleware; + use Closure; -use Symfony\Component\HttpFoundation\Cookie; -use Symfony\Component\HttpFoundation\Request; use Illuminate\Contracts\Encryption\DecryptException; use Illuminate\Contracts\Encryption\Encrypter as EncrypterContract; +use Symfony\Component\HttpFoundation\Request; +/** + * Class DecryptCookies + */ class DecryptCookies { /** @@ -35,7 +38,8 @@ class DecryptCookies /** * Create a new CookieGuard instance. * - * @param \Illuminate\Contracts\Encryption\Encrypter $encrypter + * @param \Illuminate\Contracts\Encryption\Encrypter $encrypter + * * @return void */ public function __construct(EncrypterContract $encrypter) @@ -46,19 +50,21 @@ public function __construct(EncrypterContract $encrypter) /** * Disable encryption for the given cookie name(s). * - * @param string|array $name + * @param string|array $name + * * @return void */ public function disableFor($name) { - $this->except = array_merge($this->except, (array) $name); + $this->except = array_merge($this->except, (array)$name); } /** * Handle an incoming request. * - * @param \Illuminate\Http\Request $request - * @param \Closure $next + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * * @return \Symfony\Component\HttpFoundation\Response */ public function handle($request, Closure $next) @@ -69,7 +75,8 @@ public function handle($request, Closure $next) /** * Decrypt the cookies on the request. * - * @param \Symfony\Component\HttpFoundation\Request $request + * @param \Symfony\Component\HttpFoundation\Request $request + * * @return \Symfony\Component\HttpFoundation\Request */ protected function decrypt(Request $request) @@ -92,21 +99,23 @@ protected function decrypt(Request $request) /** * Decrypt the given cookie and return the value. * - * @param string $name - * @param string|array $cookie + * @param string $name + * @param string|array $cookie + * * @return string|array */ protected function decryptCookie($name, $cookie) { return is_array($cookie) - ? $this->decryptArray($cookie) - : $this->encrypter->decrypt($cookie, static::serialized($name)); + ? $this->decryptArray($cookie) + : $this->encrypter->decrypt($cookie, static::serialized($name)); } /** * Decrypt an array based cookie. * - * @param array $cookie + * @param array $cookie + * * @return array */ protected function decryptArray(array $cookie) @@ -114,7 +123,7 @@ protected function decryptArray(array $cookie) $decrypted = []; foreach ($cookie as $key => $value) { - if (is_string($value)) { + if (\is_string($value)) { $decrypted[$key] = $this->encrypter->decrypt($value, static::serialized($key)); } } @@ -126,20 +135,22 @@ protected function decryptArray(array $cookie) * Determine whether encryption has been disabled for the given cookie. * * @param string $name + * * @return bool */ - public function isDisabled($name) + public function isDisabled(string $name) { - return in_array($name, $this->except); + return \in_array($name, $this->except); } /** * Determine if the cookie contents should be serialized. * - * @param string $name + * @param string $name + * * @return bool */ - public static function serialized($name) + public static function serialized(string $name) { return static::$serialize; } diff --git a/src/Websocket/Middleware/StartSession.php b/src/Websocket/Middleware/StartSession.php index bb5de3eb..44511480 100644 --- a/src/Websocket/Middleware/StartSession.php +++ b/src/Websocket/Middleware/StartSession.php @@ -2,11 +2,15 @@ namespace SwooleTW\Http\Websocket\Middleware; + use Closure; +use Illuminate\Contracts\Session\Session; use Illuminate\Http\Request; use Illuminate\Session\SessionManager; -use Illuminate\Contracts\Session\Session; +/** + * Class StartSession + */ class StartSession { /** @@ -19,7 +23,8 @@ class StartSession /** * Create a new session middleware. * - * @param \Illuminate\Session\SessionManager $manager + * @param \Illuminate\Session\SessionManager $manager + * * @return void */ public function __construct(SessionManager $manager) @@ -30,8 +35,9 @@ public function __construct(SessionManager $manager) /** * Handle an incoming request. * - * @param \Illuminate\Http\Request $request - * @param \Closure $next + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * * @return mixed */ public function handle($request, Closure $next) @@ -48,12 +54,13 @@ public function handle($request, Closure $next) /** * Start the session for the given request. * - * @param \Illuminate\Http\Request $request + * @param \Illuminate\Http\Request $request + * * @return \Illuminate\Contracts\Session\Session */ protected function startSession(Request $request) { - return tap($this->getSession($request), function ($session) use ($request) { + return tap($this->getSession($request), function (Session $session) use ($request) { $session->setRequestOnHandler($request); $session->start(); @@ -63,12 +70,13 @@ protected function startSession(Request $request) /** * Get the session implementation from the manager. * - * @param \Illuminate\Http\Request $request + * @param \Illuminate\Http\Request $request + * * @return \Illuminate\Contracts\Session\Session */ public function getSession(Request $request) { - return tap($this->manager->driver(), function ($session) use ($request) { + return tap($this->manager->driver(), function (Session $session) use ($request) { $session->setId($request->cookies->get($session->getName())); }); } @@ -80,6 +88,6 @@ public function getSession(Request $request) */ protected function sessionConfigured() { - return ! is_null($this->manager->getSessionConfig()['driver'] ?? null); + return !is_null($this->manager->getSessionConfig()['driver'] ?? null); } } diff --git a/src/Websocket/Parser.php b/src/Websocket/Parser.php index c8a22543..a9805048 100644 --- a/src/Websocket/Parser.php +++ b/src/Websocket/Parser.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http\Websocket; + use Illuminate\Support\Facades\App; abstract class Parser @@ -15,6 +16,9 @@ abstract class Parser * Execute strategies before decoding payload. * If return value is true will skip decoding. * + * @param \Swoole\WebSocket\Server $server + * @param \Swoole\WebSocket\Frame $frame + * * @return boolean */ public function execute($server, $frame) @@ -24,7 +28,7 @@ public function execute($server, $frame) foreach ($this->strategies as $strategy) { $result = App::call($strategy . '@handle', [ 'server' => $server, - 'frame' => $frame + 'frame' => $frame, ]); if ($result === true) { $skip = true; @@ -40,6 +44,7 @@ public function execute($server, $frame) * * @param string $event * @param mixed $data + * * @return mixed */ abstract public function encode(string $event, $data); @@ -49,6 +54,7 @@ abstract public function encode(string $event, $data); * Define and return event name and payload data here. * * @param \Swoole\Websocket\Frame $frame + * * @return array */ abstract public function decode($frame); diff --git a/src/Websocket/Push.php b/src/Websocket/Push.php new file mode 100644 index 00000000..40de4bd0 --- /dev/null +++ b/src/Websocket/Push.php @@ -0,0 +1,205 @@ +opcode = $opcode; + $this->sender = $sender; + $this->descriptors = $descriptors; + $this->broadcast = $broadcast; + $this->assigned = $assigned; + $this->event = $event; + $this->message = $message; + } + + /** + * Static constructor + * + * @param array $data + * + * @return \SwooleTW\Http\Websocket\Push + */ + public static function new(array $data) + { + $opcode = Arr::get($data, 'opcode', 1); + $sender = Arr::get($data, 'sender', 0); + $descriptors = Arr::get($data, 'fds', []); + $broadcast = Arr::get($data, 'broadcast', false); + $assigned = Arr::get($data, 'assigned', false); + $event = Arr::get($data, 'event', ''); + $message = Arr::get($data, 'message', null); + + return new static($opcode, $sender, $descriptors, $broadcast, $assigned, $event, $message); + } + + /** + * @return int + */ + public function getOpcode(): int + { + return $this->opcode; + } + + /** + * @return int + */ + public function getSender(): int + { + return $this->sender; + } + + /** + * @return array + */ + public function getDescriptors(): array + { + return $this->descriptors; + } + + /** + * @param int $descriptor + */ + public function addDescriptor($descriptor): void + { + $this->descriptors[] = $descriptor; + } + + /** + * @param array $descriptors + */ + public function mergeDescriptor(array $descriptors): void + { + $this->descriptors[] = array_merge($this->descriptors, $descriptors); + } + + /** + * @param int $descriptor + * + * @return bool + */ + public function hasDescriptor(int $descriptor): bool + { + return \in_array($descriptor, $this->descriptors, true); + } + + /** + * @return bool + */ + public function hasOwnDescriptor(): bool + { + return $this->hasDescriptor($this->sender); + } + + /** + * @return bool + */ + public function isBroadcast(): bool + { + return $this->broadcast; + } + + /** + * @return bool + */ + public function isAssigned(): bool + { + return $this->assigned; + } + + /** + * @return string + */ + public function getEvent(): string + { + return $this->event; + } + + /** + * @return string|null + */ + public function getMessage(): ?string + { + return $this->message; + } + + /** + * @return bool + */ + public function isBroadcastToAllDescriptors(): bool + { + return $this->isBroadcast() && !$this->isAssigned() && count($this->descriptors) > 0; + } + + /** + * @param int $descriptor + * + * @return bool + */ + public function isBroadcastToDescriptor(int $descriptor): bool + { + return $this->isBroadcast() && $this->getSender() === $descriptor; + } +} \ No newline at end of file diff --git a/src/Websocket/Rooms/RedisRoom.php b/src/Websocket/Rooms/RedisRoom.php index 410ac391..060ead65 100644 --- a/src/Websocket/Rooms/RedisRoom.php +++ b/src/Websocket/Rooms/RedisRoom.php @@ -2,47 +2,75 @@ namespace SwooleTW\Http\Websocket\Rooms; + +use Illuminate\Support\Arr; use Predis\Client as RedisClient; -use SwooleTW\Http\Websocket\Rooms\RoomContract; +use Predis\Pipeline\Pipeline; +/** + * Class RedisRoom + */ class RedisRoom implements RoomContract { + /** + * @var \Predis\Client + */ protected $redis; + /** + * @var array + */ protected $config; + /** + * @var string + */ protected $prefix = 'swoole:'; + /** + * RedisRoom constructor. + * + * @param array $config + */ public function __construct(array $config) { $this->config = $config; } - public function prepare(RedisClient $redis = null) + /** + * @param \Predis\Client|null $redis + * + * @return \SwooleTW\Http\Websocket\Rooms\RoomContract + */ + public function prepare(RedisClient $redis = null): RoomContract { $this->setRedis($redis); $this->setPrefix(); $this->cleanRooms(); + + return $this; } /** * Set redis client. + * + * @param \Predis\Client|null $redis */ - public function setRedis(RedisClient $redis = null) + public function setRedis(?RedisClient $redis = null) { - $server = $this->config['server'] ?? []; - $options = $this->config['options'] ?? []; + if (!$redis) { + $server = Arr::get($this->config, 'server', []); + $options = Arr::get($this->config, 'options', []); - // forbid setting prefix from options - if (array_key_exists('prefix', $options)) { - unset($options['prefix']); - } + // forbid setting prefix from options + if (Arr::has($options, 'prefix')) { + $options = Arr::except($options, 'prefix'); + } - if ($redis) { - $this->redis = $redis; - } else { - $this->redis = new RedisClient($server, $options); + $redis = new RedisClient($server, $options); } + + $this->redis = $redis; } /** @@ -50,8 +78,8 @@ public function setRedis(RedisClient $redis = null) */ protected function setPrefix() { - if (array_key_exists('prefix', $this->config)) { - $this->prefix = $this->config['prefix']; + if ($prefix = Arr::get($this->config, 'prefix')) { + $this->prefix = $prefix; } } @@ -63,35 +91,56 @@ public function getRedis() return $this->redis; } - public function add(int $fd, $roomNames) + /** + * Add multiple socket fds to a room. + * + * @param int fd + * @param array|string rooms + */ + public function add(int $fd, $rooms) { - $roomNames = is_array($roomNames) ? $roomNames : [$roomNames]; + $rooms = \is_array($rooms) ? $rooms : [$rooms]; - $this->addValue($fd, $roomNames, 'fds'); + $this->addValue($fd, $rooms, RoomContract::DESCRIPTORS_KEY); - foreach ($roomNames as $room) { - $this->addValue($room, [$fd], 'rooms'); + foreach ($rooms as $room) { + $this->addValue($room, [$fd], RoomContract::ROOMS_KEY); } } - public function delete(int $fd, $roomNames = []) + /** + * Delete multiple socket fds from a room. + * + * @param int fd + * @param array|string rooms + */ + public function delete(int $fd, $rooms) { - $roomNames = is_array($roomNames) ? $roomNames : [$roomNames]; - $roomNames = count($roomNames) ? $roomNames : $this->getRooms($fd); + $rooms = \is_array($rooms) ? $rooms : [$rooms]; + $rooms = \count($rooms) ? $rooms : $this->getRooms($fd); - $this->removeValue($fd, $roomNames, 'fds'); + $this->removeValue($fd, $rooms, RoomContract::DESCRIPTORS_KEY); - foreach ($roomNames as $room) { - $this->removeValue($room, [$fd], 'rooms'); + foreach ($rooms as $room) { + $this->removeValue($room, [$fd], RoomContract::ROOMS_KEY); } } + /** + * Add value to redis. + * + * @param $key + * @param array $values + * @param string $table + * + * @return $this + */ public function addValue($key, array $values, string $table) { $this->checkTable($table); $redisKey = $this->getKey($key, $table); - $this->redis->pipeline(function ($pipe) use ($redisKey, $values) { + $this->redis->pipeline(function (Pipeline $pipe) use ($redisKey, $values) { foreach ($values as $value) { $pipe->sadd($redisKey, $value); } @@ -100,12 +149,21 @@ public function addValue($key, array $values, string $table) return $this; } + /** + * Remove value from reddis. + * + * @param $key + * @param array $values + * @param string $table + * + * @return $this + */ public function removeValue($key, array $values, string $table) { $this->checkTable($table); $redisKey = $this->getKey($key, $table); - $this->redis->pipeline(function ($pipe) use ($redisKey, $values) { + $this->redis->pipeline(function (Pipeline $pipe) use ($redisKey, $values) { foreach ($values as $value) { $pipe->srem($redisKey, $value); } @@ -114,23 +172,50 @@ public function removeValue($key, array $values, string $table) return $this; } + /** + * Get all sockets by a room key. + * + * @param string room + * + * @return array + */ public function getClients(string $room) { - return $this->getValue($room, 'rooms'); + return $this->getValue($room, RoomContract::ROOMS_KEY) ?? []; } + /** + * Get all rooms by a fd. + * + * @param int fd + * + * @return array + */ public function getRooms(int $fd) { - return $this->getValue($fd, 'fds'); + return $this->getValue($fd, RoomContract::DESCRIPTORS_KEY) ?? []; } + /** + * Check table for rooms and descriptors. + * + * @param string $table + */ protected function checkTable(string $table) { - if (! in_array($table, ['rooms', 'fds'])) { + if (!in_array($table, [RoomContract::ROOMS_KEY, RoomContract::DESCRIPTORS_KEY])) { throw new \InvalidArgumentException('Invalid table name.'); } } + /** + * Get value. + * + * @param string $key + * @param string $table + * + * @return array + */ public function getValue(string $key, string $table) { $this->checkTable($table); @@ -138,12 +223,23 @@ public function getValue(string $key, string $table) return $this->redis->smembers($this->getKey($key, $table)); } + /** + * Get key. + * + * @param string $key + * @param string $table + * + * @return string + */ public function getKey(string $key, string $table) { return "{$this->prefix}{$table}:{$key}"; } - protected function cleanRooms() + /** + * Clean all rooms. + */ + protected function cleanRooms(): void { $keys = $this->redis->keys("{$this->prefix}*"); if (count($keys)) { diff --git a/src/Websocket/Rooms/RoomContract.php b/src/Websocket/Rooms/RoomContract.php index 8a1252a7..e3e91625 100644 --- a/src/Websocket/Rooms/RoomContract.php +++ b/src/Websocket/Rooms/RoomContract.php @@ -2,40 +2,61 @@ namespace SwooleTW\Http\Websocket\Rooms; + interface RoomContract { + /** + * Rooms key + * + * @const string + */ + public const ROOMS_KEY = 'rooms'; + + /** + * Descriptors key + * + * @const string + */ + public const DESCRIPTORS_KEY = 'fds'; + /** * Do some init stuffs before workers started. + * + * @return \SwooleTW\Http\Websocket\Rooms\RoomContract */ - public function prepare(); + public function prepare(): RoomContract; /** * Add multiple socket fds to a room. * - * @int fd - * @string|array rooms + * @param int fd + * @param array|string rooms */ public function add(int $fd, $rooms); /** * Delete multiple socket fds from a room. * - * @int fd - * @string|array rooms + * @param int fd + * @param array|string rooms */ public function delete(int $fd, $rooms); /** * Get all sockets by a room key. * - * @string room + * @param string room + * + * @return array */ public function getClients(string $room); /** * Get all rooms by a fd. * - * @int fd + * @param int fd + * + * @return array */ public function getRooms(int $fd); } diff --git a/src/Websocket/Rooms/TableRoom.php b/src/Websocket/Rooms/TableRoom.php index ad3e9146..42ddb74f 100644 --- a/src/Websocket/Rooms/TableRoom.php +++ b/src/Websocket/Rooms/TableRoom.php @@ -2,32 +2,59 @@ namespace SwooleTW\Http\Websocket\Rooms; + use Swoole\Table; -use SwooleTW\Http\Websocket\Rooms\RoomContract; class TableRoom implements RoomContract { + /** + * @var array + */ protected $config; + /** + * @var \Swoole\Table + */ protected $rooms; + /** + * @var \Swoole\Table + */ protected $fds; + /** + * TableRoom constructor. + * + * @param array $config + */ public function __construct(array $config) { $this->config = $config; } - public function prepare() + /** + * Do some init stuffs before workers started. + * + * @return \SwooleTW\Http\Websocket\Rooms\RoomContract + */ + public function prepare(): RoomContract { $this->initRoomsTable(); $this->initFdsTable(); + + return $this; } + /** + * Add multiple socket fds to a room. + * + * @param int fd + * @param array|string rooms + */ public function add(int $fd, $roomNames) { $rooms = $this->getRooms($fd); - $roomNames = is_array($roomNames) ? $roomNames : [$roomNames]; + $roomNames = \is_array($roomNames) ? $roomNames : [$roomNames]; foreach ($roomNames as $room) { $fds = $this->getClients($room); @@ -45,54 +72,92 @@ public function add(int $fd, $roomNames) $this->setRooms($fd, $rooms); } + /** + * Delete multiple socket fds from a room. + * + * @param int fd + * @param array|string rooms + */ public function delete(int $fd, $roomNames = []) { $allRooms = $this->getRooms($fd); - $roomNames = is_array($roomNames) ? $roomNames : [$roomNames]; - $rooms = count($roomNames) ? $roomNames : $allRooms; + $roomNames = \is_array($roomNames) ? $roomNames : [$roomNames]; + $rooms = \count($roomNames) ? $roomNames : $allRooms; $removeRooms = []; foreach ($rooms as $room) { $fds = $this->getClients($room); - if (! in_array($fd, $fds)) { + if (!in_array($fd, $fds)) { continue; } - $this->setClients($room, array_values(array_diff($fds, [$fd])), 'rooms'); + $this->setClients($room, array_values(array_diff($fds, [$fd]))); $removeRooms[] = $room; } - $this->setRooms($fd, array_values(array_diff($allRooms, $removeRooms)), 'fds'); + $this->setRooms($fd, collect($allRooms)->diff($removeRooms)->values()->toArray()); } + /** + * Get all sockets by a room key. + * + * @param string room + * + * @return array + */ public function getClients(string $room) { - return $this->getValue($room, 'rooms'); + return $this->getValue($room, RoomContract::ROOMS_KEY) ?? []; } + /** + * Get all rooms by a fd. + * + * @param int fd + * + * @return array + */ public function getRooms(int $fd) { - return $this->getValue($fd, 'fds'); + return $this->getValue($fd, RoomContract::DESCRIPTORS_KEY) ?? []; } - protected function setClients(string $room, array $fds) + /** + * @param string $room + * @param array $fds + * + * @return \SwooleTW\Http\Websocket\Rooms\TableRoom + */ + protected function setClients(string $room, array $fds): TableRoom { - return $this->setValue($room, $fds, 'rooms'); + return $this->setValue($room, $fds, RoomContract::ROOMS_KEY); } - protected function setRooms(int $fd, array $rooms) + /** + * @param int $fd + * @param array $rooms + * + * @return \SwooleTW\Http\Websocket\Rooms\TableRoom + */ + protected function setRooms(int $fd, array $rooms): TableRoom { - return $this->setValue($fd, $rooms, 'fds'); + return $this->setValue($fd, $rooms, RoomContract::DESCRIPTORS_KEY); } - protected function initRoomsTable() + /** + * Init rooms table + */ + protected function initRoomsTable(): void { $this->rooms = new Table($this->config['room_rows']); $this->rooms->column('value', Table::TYPE_STRING, $this->config['room_size']); $this->rooms->create(); } + /** + * Init descriptors table + */ protected function initFdsTable() { $this->fds = new Table($this->config['client_rows']); @@ -100,17 +165,34 @@ protected function initFdsTable() $this->fds->create(); } + /** + * Set value to table + * + * @param $key + * @param array $value + * @param string $table + * + * @return $this + */ public function setValue($key, array $value, string $table) { $this->checkTable($table); $this->$table->set($key, [ - 'value' => json_encode($value) + 'value' => json_encode($value), ]); return $this; } + /** + * Get value from table + * + * @param string $key + * @param string $table + * + * @return array|mixed + */ public function getValue(string $key, string $table) { $this->checkTable($table); @@ -120,9 +202,14 @@ public function getValue(string $key, string $table) return $value ? json_decode($value['value'], true) : []; } + /** + * Check table for exists + * + * @param string $table + */ protected function checkTable(string $table) { - if (! property_exists($this, $table) || ! $this->$table instanceof Table) { + if (!property_exists($this, $table) || !$this->$table instanceof Table) { throw new \InvalidArgumentException('Invalid table name.'); } } diff --git a/src/Websocket/SimpleParser.php b/src/Websocket/SimpleParser.php index a052dafc..1b0cadd0 100644 --- a/src/Websocket/SimpleParser.php +++ b/src/Websocket/SimpleParser.php @@ -2,8 +2,6 @@ namespace SwooleTW\Http\Websocket; -use Swoole\Websocket\Server; -use SwooleTW\Http\Websocket\Parser; class SimpleParser extends Parser { @@ -17,13 +15,14 @@ class SimpleParser extends Parser * * @param string $event * @param mixed $data + * * @return mixed */ public function encode(string $event, $data) { return json_encode([ 'event' => $event, - 'data' => $data + 'data' => $data, ]); } @@ -32,6 +31,7 @@ public function encode(string $event, $data) * Define and return event name and payload data here. * * @param \Swoole\Websocket\Frame $frame + * * @return array */ public function decode($frame) @@ -40,7 +40,7 @@ public function decode($frame) return [ 'event' => $data['event'] ?? null, - 'data' => $data['data'] ?? null + 'data' => $data['data'] ?? null, ]; } } diff --git a/src/Websocket/SocketIO/Packet.php b/src/Websocket/SocketIO/Packet.php index 07a4188a..bb7b83e4 100644 --- a/src/Websocket/SocketIO/Packet.php +++ b/src/Websocket/SocketIO/Packet.php @@ -2,6 +2,10 @@ namespace SwooleTW\Http\Websocket\SocketIO; + +/** + * Class Packet + */ class Packet { /** @@ -84,7 +88,7 @@ class Packet 3 => 'PONG', 4 => 'MESSAGE', 5 => 'UPGRADE', - 6 => 'NOOP' + 6 => 'NOOP', ]; /** @@ -97,25 +101,33 @@ class Packet 3 => 'ACK', 4 => 'ERROR', 5 => 'BINARY_EVENT', - 6 => 'BINARY_ACK' + 6 => 'BINARY_ACK', ]; /** * Get socket packet type of a raw payload. + * + * @param string $packet + * + * @return int|null */ public static function getSocketType(string $packet) { $type = $packet[0] ?? null; - if (! array_key_exists($type, static::$socketTypes)) { + if (!array_key_exists($type, static::$socketTypes)) { return null; } - return (int) $type; + return (int)$type; } /** * Get data packet from a raw payload. + * + * @param string $packet + * + * @return array|null */ public static function getPayload(string $packet) { @@ -135,12 +147,17 @@ public static function getPayload(string $packet) return [ 'event' => $data[0], - 'data' => $data[1] ?? null + 'data' => $data[1] ?? null, ]; } /** * Return if a socket packet belongs to specific type. + * + * @param $packet + * @param string $typeName + * + * @return bool */ public static function isSocketType($packet, string $typeName) { diff --git a/src/Websocket/SocketIO/SocketIOParser.php b/src/Websocket/SocketIO/SocketIOParser.php index 8c3e50d6..8272ba4a 100644 --- a/src/Websocket/SocketIO/SocketIOParser.php +++ b/src/Websocket/SocketIO/SocketIOParser.php @@ -2,17 +2,20 @@ namespace SwooleTW\Http\Websocket\SocketIO; + use SwooleTW\Http\Websocket\Parser; -use SwooleTW\Http\Websocket\SocketIO\Packet; use SwooleTW\Http\Websocket\SocketIO\Strategies\HeartbeatStrategy; +/** + * Class SocketIOParser + */ class SocketIOParser extends Parser { /** * Strategy classes need to implement handle method. */ protected $strategies = [ - HeartbeatStrategy::class + HeartbeatStrategy::class, ]; /** @@ -20,6 +23,7 @@ class SocketIOParser extends Parser * * @param string $event * @param mixed $data + * * @return mixed */ public function encode(string $event, $data) @@ -37,6 +41,7 @@ public function encode(string $event, $data) * Define and return payload here. * * @param \Swoole\Websocket\Frame $frame + * * @return array */ public function decode($frame) @@ -45,7 +50,7 @@ public function decode($frame) return [ 'event' => $payload['event'] ?? null, - 'data' => $payload['data'] ?? null + 'data' => $payload['data'] ?? null, ]; } } diff --git a/src/Websocket/SocketIO/Strategies/HeartbeatStrategy.php b/src/Websocket/SocketIO/Strategies/HeartbeatStrategy.php index e1fe7c64..88a8ae16 100644 --- a/src/Websocket/SocketIO/Strategies/HeartbeatStrategy.php +++ b/src/Websocket/SocketIO/Strategies/HeartbeatStrategy.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http\Websocket\SocketIO\Strategies; + use SwooleTW\Http\Websocket\SocketIO\Packet; class HeartbeatStrategy @@ -9,6 +10,9 @@ class HeartbeatStrategy /** * If return value is true will skip decoding. * + * @param \Swoole\WebSocket\Server $server + * @param \Swoole\WebSocket\Frame $frame + * * @return boolean */ public function handle($server, $frame) diff --git a/src/Websocket/SocketIO/WebsocketHandler.php b/src/Websocket/SocketIO/WebsocketHandler.php index c78f6498..34b0e34e 100644 --- a/src/Websocket/SocketIO/WebsocketHandler.php +++ b/src/Websocket/SocketIO/WebsocketHandler.php @@ -2,12 +2,12 @@ namespace SwooleTW\Http\Websocket\SocketIO; -use Swoole\Websocket\Frame; + use Illuminate\Http\Request; use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\Config; +use Swoole\Websocket\Frame; use SwooleTW\Http\Websocket\HandlerContract; -use SwooleTW\Http\Websocket\SocketIO\Packet; class WebsocketHandler implements HandlerContract { @@ -16,15 +16,17 @@ class WebsocketHandler implements HandlerContract * * @param int $fd * @param \Illuminate\Http\Request $request + * + * @return bool */ public function onOpen($fd, Request $request) { - if (! $request->input('sid')) { + if (!$request->input('sid')) { $payload = json_encode([ 'sid' => base64_encode(uniqid()), 'upgrades' => [], 'pingInterval' => Config::get('swoole_websocket.ping_interval'), - 'pingTimeout' => Config::get('swoole_websocket.ping_timeout') + 'pingTimeout' => Config::get('swoole_websocket.ping_timeout'), ]); $initPayload = Packet::OPEN . $payload; $connectPayload = Packet::MESSAGE . Packet::CONNECT; diff --git a/src/Websocket/Websocket.php b/src/Websocket/Websocket.php index d0da2d59..caad0773 100644 --- a/src/Websocket/Websocket.php +++ b/src/Websocket/Websocket.php @@ -2,13 +2,13 @@ namespace SwooleTW\Http\Websocket; -use InvalidArgumentException; + +use Illuminate\Contracts\Container\Container; +use Illuminate\Contracts\Pipeline\Pipeline as PipelineContract; use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\Config; -use SwooleTW\Http\Websocket\Authenticatable; -use Illuminate\Contracts\Container\Container; +use InvalidArgumentException; use SwooleTW\Http\Websocket\Rooms\RoomContract; -use Illuminate\Contracts\Pipeline\Pipeline as PipelineContract; class Websocket { @@ -56,14 +56,14 @@ class Websocket /** * Pipeline instance. * - * @var PipelineContract + * @var \Illuminate\Contracts\Pipeline\Pipeline */ protected $pipeline; /** * Room adapter. * - * @var RoomContract + * @var \SwooleTW\Http\Websocket\Rooms\RoomContract */ protected $room; @@ -94,14 +94,15 @@ public function broadcast() * Set multiple recipients fd or room names. * * @param integer, string, array + * * @return $this */ - public function to($values) + public function to($values): self { $values = is_string($values) || is_integer($values) ? func_get_args() : $values; foreach ($values as $value) { - if (! in_array($value, $this->to)) { + if (!in_array($value, $this->to)) { $this->to[] = $value; } } @@ -113,9 +114,10 @@ public function to($values) * Join sender to multiple rooms. * * @param string, array $rooms + * * @return $this */ - public function join($rooms) + public function join($rooms): self { $rooms = is_string($rooms) || is_integer($rooms) ? func_get_args() : $rooms; @@ -127,10 +129,11 @@ public function join($rooms) /** * Make sender leave multiple rooms. * - * @param string, array + * @param array $rooms + * * @return $this */ - public function leave($rooms = []) + public function leave($rooms = []): self { $rooms = is_string($rooms) || is_integer($rooms) ? func_get_args() : $rooms; @@ -144,12 +147,13 @@ public function leave($rooms = []) * * @param string * @param mixed + * * @return boolean */ - public function emit(string $event, $data) + public function emit(string $event, $data): bool { $fds = $this->getFds(); - $assigned = ! empty($this->to); + $assigned = !empty($this->to); // if no fds are found, but rooms are assigned // that means trying to emit to a non-existing room @@ -166,8 +170,8 @@ public function emit(string $event, $data) 'broadcast' => $this->isBroadcast, 'assigned' => $assigned, 'event' => $event, - 'message' => $data - ] + 'message' => $data, + ], ]); $this->reset(); @@ -179,6 +183,7 @@ public function emit(string $event, $data) * An alias of `join` function. * * @param string + * * @return $this */ public function in($room) @@ -193,11 +198,12 @@ public function in($room) * * @param string * @param callback + * * @return $this */ public function on(string $event, $callback) { - if (! is_string($callback) && ! is_callable($callback)) { + if (!is_string($callback) && !is_callable($callback)) { throw new InvalidArgumentException( 'Invalid websocket callback. Must be a string or callable.' ); @@ -212,6 +218,7 @@ public function on(string $event, $callback) * Check if this event name exists. * * @param string + * * @return boolean */ public function eventExists(string $event) @@ -224,11 +231,12 @@ public function eventExists(string $event) * * @param string * @param mixed + * * @return mixed */ public function call(string $event, $data = null) { - if (! $this->eventExists($event)) { + if (!$this->eventExists($event)) { return null; } @@ -243,7 +251,7 @@ public function call(string $event, $data = null) return App::call($this->callbacks[$event], [ 'websocket' => $this, - $dataKey => $data + $dataKey => $data, ]); } @@ -251,6 +259,7 @@ public function call(string $event, $data = null) * Close current connection. * * @param integer + * * @return boolean */ public function close(int $fd = null) @@ -262,6 +271,7 @@ public function close(int $fd = null) * Set sender fd. * * @param integer + * * @return $this */ public function setSender(int $fd) @@ -320,6 +330,10 @@ protected function getFds() /** * Reset some data status. + * + * @param bool $force + * + * @return \SwooleTW\Http\Websocket\Websocket */ public function reset($force = false) { @@ -336,6 +350,10 @@ public function reset($force = false) /** * Get or set middleware. + * + * @param array|string|null $middleware + * + * @return array|\SwooleTW\Http\Websocket\Websocket */ public function middleware($middleware = null) { @@ -362,6 +380,8 @@ protected function setDefaultMiddleware() /** * Set container to pipeline. + * + * @param \Illuminate\Contracts\Container\Container $container */ public function setContainer(Container $container) { @@ -377,6 +397,10 @@ public function setContainer(Container $container) /** * Set pipeline. + * + * @param \Illuminate\Contracts\Pipeline\Pipeline $pipeline + * + * @return \SwooleTW\Http\Websocket\Websocket */ public function setPipeline(PipelineContract $pipeline) { @@ -396,7 +420,8 @@ public function getPipeline() /** * Set the given request through the middleware. * - * @param \Illuminate\Http\Request $request + * @param \Illuminate\Http\Request $request + * * @return \Illuminate\Http\Request */ protected function setRequestThroughMiddleware($request) diff --git a/stubs/5.5/MySqlConnector.stub b/stubs/5.5/MySqlConnector.stub new file mode 100644 index 00000000..45281ac0 --- /dev/null +++ b/stubs/5.5/MySqlConnector.stub @@ -0,0 +1,53 @@ +causedByLostConnection($e) || Str::contains($e->getMessage(), 'is closed')) { + return $this->createPdoConnection($dsn, $username, $password, $options); + } + + throw $e; + } +} diff --git a/stubs/5.6/MySqlConnector.stub b/stubs/5.6/MySqlConnector.stub new file mode 100644 index 00000000..7082d761 --- /dev/null +++ b/stubs/5.6/MySqlConnector.stub @@ -0,0 +1,53 @@ +causedByLostConnection($e) || Str::contains($e->getMessage(), 'is closed')) { + return $this->createPdoConnection($dsn, $username, $password, $options); + } + + throw $e; + } +} diff --git a/stubs/5.6/SwooleTaskQueue.stub b/stubs/5.6/SwooleTaskQueue.stub new file mode 100644 index 00000000..be9a2422 --- /dev/null +++ b/stubs/5.6/SwooleTaskQueue.stub @@ -0,0 +1,114 @@ +swoole = $swoole; + } + + /** + * Push a new job onto the queue. + * + * @param string|object $job + * @param mixed $data + * @param string $queue + * + * @return mixed + */ + public function push($job, $data = '', $queue = null) + { + return $this->pushRaw($this->createPayload($job, $data), $queue); + } + + /** + * Push a raw payload onto the queue. + * + * @param string $payload + * @param string $queue + * @param array $options + * + * @return mixed + */ + public function pushRaw($payload, $queue = null, array $options = []) + { + return $this->swoole->task($payload, !is_numeric($queue) ? 1 : (int)$queue); + } + + /** + * Push a new job onto the queue after a delay. + * + * @param \DateTimeInterface|\DateInterval|int $delay + * @param string|object $job + * @param mixed $data + * @param string $queue + * + * @return mixed + */ + public function later($delay, $job, $data = '', $queue = null) + { + return Timer::after($this->secondsUntil($delay) * 1000, function () use ($job, $data, $queue) { + return $this->push($job, $data, $queue); + }); + } + + /** + * Create a typical, string based queue payload array. + * + * @param string $job + * @param mixed $data + * + * @throws \Exception + */ + protected function createStringPayload($job, $data) + { + throw new Exception('Unsupported empty data'); + } + + /** + * Get the size of the queue. + * + * @param string $queue + * + * @return int + */ + public function size($queue = null) + { + return -1; + } + + /** + * Pop the next job off of the queue. + * + * @param string $queue + * + * @return \Illuminate\Contracts\Queue\Job|null + */ + public function pop($queue = null) + { + return null; + } +} diff --git a/stubs/5.7/SwooleTaskQueue.stub b/stubs/5.7/SwooleTaskQueue.stub new file mode 100644 index 00000000..0a28fedf --- /dev/null +++ b/stubs/5.7/SwooleTaskQueue.stub @@ -0,0 +1,115 @@ +swoole = $swoole; + } + + /** + * Push a new job onto the queue. + * + * @param string|object $job + * @param mixed $data + * @param string $queue + * + * @return mixed + */ + public function push($job, $data = '', $queue = null) + { + return $this->pushRaw($this->createPayload($job, $data), $queue); + } + + /** + * Push a raw payload onto the queue. + * + * @param string $payload + * @param string $queue + * @param array $options + * + * @return mixed + */ + public function pushRaw($payload, $queue = null, array $options = []) + { + return $this->swoole->task($payload, !is_numeric($queue) ? 1 : (int)$queue); + } + + /** + * Push a new job onto the queue after a delay. + * + * @param \DateTimeInterface|\DateInterval|int $delay + * @param string|object $job + * @param mixed $data + * @param string $queue + * + * @return mixed + */ + public function later($delay, $job, $data = '', $queue = null) + { + return Timer::after($this->secondsUntil($delay) * 1000, function () use ($job, $data, $queue) { + return $this->push($job, $data, $queue); + }); + } + + /** + * Create a typical, string based queue payload array. + * + * @param string $job + * @param string $queue + * @param mixed $data + * + * @throws \Exception + */ + protected function createStringPayload($job, $queue, $data) + { + throw new Exception('Unsupported empty data'); + } + + /** + * Get the size of the queue. + * + * @param string $queue + * + * @return int + */ + public function size($queue = null) + { + return -1; + } + + /** + * Pop the next job off of the queue. + * + * @param string $queue + * + * @return \Illuminate\Contracts\Queue\Job|null + */ + public function pop($queue = null) + { + return null; + } +} diff --git a/tests/Coroutine/ConnectorFactoryTest.php b/tests/Coroutine/ConnectorFactoryTest.php new file mode 100644 index 00000000..d47169f4 --- /dev/null +++ b/tests/Coroutine/ConnectorFactoryTest.php @@ -0,0 +1,45 @@ +=') ? '5.6' : '5.5'; + $stub = ConnectorFactory::stub($version); + + $this->assertTrue(Str::contains($stub, $search)); + } + + public function testItCanCompareNeededStubByVersion() + { + $version = '5.5'; + $search = '5.6'; + + $stub = ConnectorFactory::stub($version); + + $this->assertNotTrue(Str::contains($stub, $search)); + } + + public function testItCanMakeNeededQueueByVersion() + { + $version = FW::version(); + $queue = ConnectorFactory::make($version); + + $this->assertInstanceOf(ConnectorFactory::CONNECTOR_CLASS, $queue); + } +} \ No newline at end of file diff --git a/tests/Coroutine/ContextTest.php b/tests/Coroutine/ContextTest.php index fb5c6c36..d413482e 100644 --- a/tests/Coroutine/ContextTest.php +++ b/tests/Coroutine/ContextTest.php @@ -2,11 +2,12 @@ namespace SwooleTW\Http\Tests\Coroutine; -use TypeError; -use Mockery as m; -use SwooleTW\Http\Tests\TestCase; + use Illuminate\Container\Container; +use Mockery as m; use SwooleTW\Http\Coroutine\Context; +use SwooleTW\Http\Tests\TestCase; +use TypeError; class ContextTest extends TestCase { diff --git a/tests/Server/ManagerTest.php b/tests/Server/ManagerTest.php index d0b80fc7..69740c8c 100644 --- a/tests/Server/ManagerTest.php +++ b/tests/Server/ManagerTest.php @@ -2,26 +2,27 @@ namespace SwooleTW\Http\Tests\Server; + +use Illuminate\Container\Container; +use Illuminate\Contracts\Debug\ExceptionHandler; +use Illuminate\Support\Facades\Config; +use Laravel\Lumen\Exceptions\Handler; use Mockery as m; -use Swoole\Table; use Swoole\Http\Request; use Swoole\Http\Response; +use Swoole\Table; use SwooleTW\Http\Server\Manager; use SwooleTW\Http\Server\Sandbox; -use SwooleTW\Http\Tests\TestCase; -use Illuminate\Container\Container; -use SwooleTW\Http\Websocket\Parser; use SwooleTW\Http\Table\SwooleTable; -use Swoole\Http\Server as HttpServer; -use Illuminate\Support\Facades\Config; -use SwooleTW\Http\Websocket\Websocket; +use SwooleTW\Http\Tests\TestCase; +use SwooleTW\Http\Websocket\Facades\Websocket as WebsocketFacade; use SwooleTW\Http\Websocket\HandlerContract; -use SwooleTW\Http\Websocket\Rooms\TableRoom; +use SwooleTW\Http\Websocket\Parser; use SwooleTW\Http\Websocket\Rooms\RoomContract; -use Illuminate\Contracts\Debug\ExceptionHandler; +use SwooleTW\Http\Websocket\Rooms\TableRoom; use SwooleTW\Http\Websocket\SocketIO\SocketIOParser; use SwooleTW\Http\Websocket\SocketIO\WebsocketHandler; -use SwooleTW\Http\Websocket\Facades\Websocket as WebsocketFacade; +use SwooleTW\Http\Websocket\Websocket; class ManagerTest extends TestCase { @@ -31,13 +32,13 @@ class ManagerTest extends TestCase 'table_name' => [ 'size' => 1024, 'columns' => [ - ['name' => 'column_name', 'type' => Table::TYPE_STRING, 'size' => 1024] - ] - ] + ['name' => 'column_name', 'type' => Table::TYPE_STRING, 'size' => 1024], + ], + ], ], 'swoole_http.providers' => [], 'swoole_http.resetters' => [], - 'swoole_http.pre_resolved' => ['foo'] + 'swoole_http.pre_resolved' => ['foo'], ]; protected $websocketConfig = [ @@ -49,13 +50,13 @@ class ManagerTest extends TestCase 'room_rows' => 10, 'room_size' => 10, 'client_rows' => 10, - 'client_size' => 10 + 'client_size' => 10, ], 'swoole_websocket.drivers.table' => TableRoom::class, 'swoole_http.tables' => [], 'swoole_http.providers' => [], 'swoole_http.resetters' => [], - 'swoole_http.server.public_path' => '/' + 'swoole_http.server.public_path' => '/', ]; public function testGetFramework() @@ -74,7 +75,7 @@ public function testGetWebsocketParser() { $manager = $this->getWebsocketManager(); - $this->assertTrue($manager->getParser() instanceof SocketIOParser); + $this->assertTrue($manager->getPayloadParser() instanceof SocketIOParser); } public function testRun() @@ -127,7 +128,7 @@ public function testOnManagerStart() public function testOnWorkerStart() { $server = $this->getServer(); - $manager = $this->getManager(); + $this->getManager(); $container = $this->getContainer($this->getServer(), $this->getConfig(true)); $container->singleton('events', function () { @@ -153,7 +154,7 @@ public function testOnWorkerStart() public function testLoadApplication() { $server = $this->getServer(); - $manager = $this->getManager(); + $this->getManager(); $container = $this->getContainer($this->getServer(), $this->getConfig()); $container->singleton('events', function () { @@ -164,7 +165,7 @@ public function testLoadApplication() $manager = $this->getManager($container, $framework = 'laravel', $path); $manager->onWorkerStart($server); - $app = $manager->getApplication(); + $manager->getApplication(); } public function testOnTaskWorkerStart() @@ -184,8 +185,8 @@ public function testOnTaskWorkerStart() public function testOnRequest() { - $server = $this->getServer(); - $manager = $this->getManager(); + $this->getServer(); + $this->getManager(); $container = $this->getContainer($this->getServer(), $this->getConfig(true)); $container->singleton('events', function () { @@ -196,6 +197,7 @@ public function testOnRequest() $websocket->shouldReceive('reset') ->with(true) ->once(); + return $websocket; }); $container->singleton('swoole.sandbox', function () { @@ -210,6 +212,7 @@ public function testOnRequest() ->once(); $sandbox->shouldReceive('disable') ->once(); + return $sandbox; }); @@ -249,12 +252,14 @@ public function testOnRequestException() $sandbox = m::mock(Sandbox::class); $sandbox->shouldReceive('disable') ->once(); + return $sandbox; }); $container->singleton(ExceptionHandler::class, function () { $handler = m::mock(ExceptionHandler::class); $handler->shouldReceive('render') ->once(); + return $handler; }); @@ -316,9 +321,9 @@ public function testSetParser() { $parser = m::mock(Parser::class); $manager = $this->getManager(); - $manager->setParser($parser); + $manager->setPayloadParser($parser); - $this->assertSame($parser, $manager->getParser()); + $this->assertSame($parser, $manager->getPayloadParser()); } public function testSetWebsocketHandler() @@ -339,6 +344,7 @@ public function testLogServerError() $handler->shouldReceive('report') ->with($exception) ->once(); + return $handler; }); $manager = $this->getManager($container); @@ -371,9 +377,10 @@ public function testOnOpen() $websocket->shouldReceive('setContainer') ->with(m::type(Container::class)) ->once(); - $websocket->shouldReceive('call') + $websocket->shouldReceive('call') ->with('connect', m::type('Illuminate\Http\Request')) ->once(); + return $websocket; }); $container->singleton('swoole.sandbox', function () { @@ -388,6 +395,7 @@ public function testOnOpen() $sandbox->shouldReceive('getApplication') ->once() ->andReturn(m::mock(Container::class)); + return $sandbox; }); @@ -399,7 +407,7 @@ public function testOnOpen() $manager = $this->getWebsocketManager(); $manager->setApplication($container); $manager->setWebsocketHandler($handler); - $manager->onOpen('server', $request); + $manager->onOpen($request); } public function testOnMessage() @@ -417,7 +425,7 @@ public function testOnMessage() ->once() ->andReturn($payload = [ 'event' => 'event', - 'data' => 'data' + 'data' => 'data', ]); $container = $this->getContainer(); @@ -437,6 +445,7 @@ public function testOnMessage() $websocket->shouldReceive('call') ->with($payload['event'], $payload['data']) ->once(); + return $websocket; }); $container->singleton('swoole.sandbox', function () { @@ -445,12 +454,13 @@ public function testOnMessage() ->once(); $sandbox->shouldReceive('disable') ->once(); + return $sandbox; }); $manager = $this->getWebsocketManager(); $manager->setApplication($container); - $manager->setParser($parser); + $manager->setPayloadParser($parser); $manager->onMessage('server', $frame); } @@ -476,6 +486,7 @@ public function testOnClose() ->once(); $websocket->shouldReceive('leave') ->once(); + return $websocket; }); @@ -492,8 +503,9 @@ public function testOnClose() ->with($fd) ->once() ->andReturn([ - 'websocket_status' => true + 'websocket_status' => true, ]); + return $server; }); @@ -511,7 +523,7 @@ public function testNormalizePushMessage() 'broadcast' => 'broadcast', 'assigned' => 'assigned', 'event' => 'event', - 'message' => 'message' + 'message' => 'message', ]; $manager = $this->getWebsocketManager(); @@ -531,7 +543,7 @@ public function testPushMessage() $data = [ 'fds' => [1, 2, 3], 'event' => 'event', - 'message' => 'message' + 'message' => 'message', ]; $parser = m::mock(Parser::class); @@ -548,7 +560,7 @@ public function testPushMessage() ->times(count($data['fds'])); $manager = $this->getWebsocketManager(); - $manager->setParser($parser); + $manager->setPayloadParser($parser); $manager->pushMessage($server, $data); } @@ -574,6 +586,7 @@ protected function getContainer($server = null, $config = null) $container->singleton('swoole.server', function () use ($server) { return $server; }); + $container->singleton(ExceptionHandler::class, Handler::class); return $container; } diff --git a/tests/Server/ResettersTest.php b/tests/Server/ResettersTest.php index ff416dc2..d2675fcb 100644 --- a/tests/Server/ResettersTest.php +++ b/tests/Server/ResettersTest.php @@ -2,22 +2,23 @@ namespace SwooleTW\Http\Tests\Server; -use Mockery as m; -use Illuminate\Http\Request; -use SwooleTW\Http\Server\Sandbox; -use SwooleTW\Http\Tests\TestCase; + use Illuminate\Container\Container; use Illuminate\Contracts\Http\Kernel; +use Illuminate\Http\Request; use Illuminate\Support\ServiceProvider; +use Mockery as m; use SwooleTW\Http\Server\Resetters\BindRequest; -use SwooleTW\Http\Server\Resetters\ResetConfig; -use SwooleTW\Http\Server\Resetters\ResetCookie; -use SwooleTW\Http\Server\Resetters\ResetSession; use SwooleTW\Http\Server\Resetters\ClearInstances; -use SwooleTW\Http\Server\Resetters\ResetProviders; -use SwooleTW\Http\Server\Resetters\RebindViewContainer; use SwooleTW\Http\Server\Resetters\RebindKernelContainer; use SwooleTW\Http\Server\Resetters\RebindRouterContainer; +use SwooleTW\Http\Server\Resetters\RebindViewContainer; +use SwooleTW\Http\Server\Resetters\ResetConfig; +use SwooleTW\Http\Server\Resetters\ResetCookie; +use SwooleTW\Http\Server\Resetters\ResetProviders; +use SwooleTW\Http\Server\Resetters\ResetSession; +use SwooleTW\Http\Server\Sandbox; +use SwooleTW\Http\Tests\TestCase; class ResettersTest extends TestCase { @@ -233,7 +234,13 @@ public function testResetProviders() } } -class TestProvider extends ServiceProvider { - public function register() {} - public function boot() {} +class TestProvider extends ServiceProvider +{ + public function register() + { + } + + public function boot() + { + } } diff --git a/tests/Server/SandboxTest.php b/tests/Server/SandboxTest.php index 9f04a1e6..ee4e02cf 100644 --- a/tests/Server/SandboxTest.php +++ b/tests/Server/SandboxTest.php @@ -2,21 +2,18 @@ namespace SwooleTW\Http\Tests\Server; -use Mockery as m; -use RuntimeException; -use Swoole\Coroutine; -use ReflectionProperty; -use Illuminate\Http\Request; + use Illuminate\Config\Repository; -use SwooleTW\Http\Server\Sandbox; -use SwooleTW\Http\Tests\TestCase; use Illuminate\Container\Container; +use Illuminate\Contracts\Container\Container as ContainerContract; +use Illuminate\Http\Request; +use Mockery as m; use SwooleTW\Http\Coroutine\Context; -use SwooleTW\Http\Server\Application; -use Illuminate\Support\Facades\Facade; use SwooleTW\Http\Exceptions\SandboxException; +use SwooleTW\Http\Server\Application; use SwooleTW\Http\Server\Resetters\ResetterContract; -use Illuminate\Contracts\Container\Container as ContainerContract; +use SwooleTW\Http\Server\Sandbox; +use SwooleTW\Http\Tests\TestCase; class SandboxTest extends TestCase { @@ -99,6 +96,31 @@ public function testGetApplication() $this->assertTrue($sandbox->getSnapshot() instanceof Container); } + public function testGetCachedSnapshot() + { + $container = m::mock(Container::class); + $snapshot = m::mock(Container::class); + $snapshot->shouldReceive('offsetGet') + ->with('foo') + ->once() + ->andReturn($result = 'bar'); + + $sandbox = new Sandbox; + $sandbox->setBaseApp($container); + $sandbox->setSnapshot($snapshot); + + $this->assertTrue($sandbox->getApplication() instanceof Container); + $this->assertEquals($result, $sandbox->getApplication()->foo); + } + + public function testRunWithoutSnapshot() + { + $this->expectException(SandboxException::class); + + $sandbox = new Sandbox; + $sandbox->run($request = m::mock(Request::class)); + } + public function testSetRequest() { $request = m::mock(Request::class); @@ -143,7 +165,8 @@ protected function getContainer() } } -class TestResetter implements ResetterContract { +class TestResetter implements ResetterContract +{ public function handle(ContainerContract $app, Sandbox $sandbox) { return 'foo'; diff --git a/tests/SocketIO/PacketTest.php b/tests/SocketIO/PacketTest.php index 484b2d9b..e2b7b20d 100644 --- a/tests/SocketIO/PacketTest.php +++ b/tests/SocketIO/PacketTest.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http\Tests\SocketIO; + use SwooleTW\Http\Tests\TestCase; use SwooleTW\Http\Websocket\SocketIO\Packet; @@ -33,35 +34,35 @@ public function testGetPayload() $packet = '42["foo","bar"]'; $this->assertSame([ 'event' => 'foo', - 'data' => 'bar' + 'data' => 'bar', ], Packet::getPayload($packet)); $packet = '42["foo", "bar"]'; $this->assertSame([ 'event' => 'foo', - 'data' => 'bar' + 'data' => 'bar', ], Packet::getPayload($packet)); $packet = '42["foo",{"message":"test"}]'; $this->assertSame([ 'event' => 'foo', 'data' => [ - 'message' => 'test' - ] + 'message' => 'test', + ], ], Packet::getPayload($packet)); $packet = '42["foo", {"message":"test"}]'; $this->assertSame([ 'event' => 'foo', 'data' => [ - 'message' => 'test' - ] + 'message' => 'test', + ], ], Packet::getPayload($packet)); $packet = '42["foo"]'; $this->assertSame([ 'event' => 'foo', - 'data' => null + 'data' => null, ], Packet::getPayload($packet)); } diff --git a/tests/SocketIO/ParserTest.php b/tests/SocketIO/ParserTest.php index ff8c613f..346a829c 100644 --- a/tests/SocketIO/ParserTest.php +++ b/tests/SocketIO/ParserTest.php @@ -2,10 +2,11 @@ namespace SwooleTW\Http\Tests\SocketIO; + +use Illuminate\Support\Facades\App; use Mockery as m; use Swoole\Websocket\Frame; use SwooleTW\Http\Tests\TestCase; -use Illuminate\Support\Facades\App; use SwooleTW\Http\Websocket\SocketIO\SocketIOParser; use SwooleTW\Http\Websocket\SocketIO\Strategies\HeartbeatStrategy; @@ -24,7 +25,7 @@ public function testEncode() $data = ['message' => 'test']; $this->assertSame('42["foo",{"message":"test"}]', $parser->encode($event, $data)); - $data = (object) ['message' => 'test']; + $data = (object)['message' => 'test']; $this->assertSame('42["foo",{"message":"test"}]', $parser->encode($event, $data)); } @@ -38,15 +39,15 @@ public function testDecode() $this->assertSame([ 'event' => 'foo', 'data' => [ - 'message' => 'test' - ] + 'message' => 'test', + ], ], $parser->decode($frame)); $payload = '42["foo","bar"]'; $frame->data = $payload; $this->assertSame([ 'event' => 'foo', - 'data' => 'bar' + 'data' => 'bar', ], $parser->decode($frame)); } diff --git a/tests/SocketIO/SocketIOControllerTest.php b/tests/SocketIO/SocketIOControllerTest.php index a805a767..d9a9f78d 100644 --- a/tests/SocketIO/SocketIOControllerTest.php +++ b/tests/SocketIO/SocketIOControllerTest.php @@ -2,11 +2,12 @@ namespace SwooleTW\Http\Tests\SocketIO; -use Mockery as m; + use Illuminate\Http\Request; -use SwooleTW\Http\Tests\TestCase; use Illuminate\Support\Facades\Config; +use Mockery as m; use SwooleTW\Http\Controllers\SocketIOController; +use SwooleTW\Http\Tests\TestCase; class SocketIOControllerTest extends TestCase { @@ -24,8 +25,9 @@ public function testUnknownTransport() ->once() ->with([ 'code' => 0, - 'message' => 'Transport unknown' + 'message' => 'Transport unknown', ], 400); + return $response; }); @@ -66,6 +68,7 @@ public function testUpgradePayload() $base64Encode = false; $this->mockMethod('base64_encode', function () use (&$base64Encode) { $base64Encode = true; + return 'payload'; }); @@ -82,7 +85,7 @@ public function testUpgradePayload() 'sid' => 'payload', 'upgrades' => ['websocket'], 'pingInterval' => 1, - 'pingTimeout' => 1 + 'pingTimeout' => 1, ]); $expectedPayload = '97:0' . $expectedPayload . '2:40'; @@ -95,21 +98,20 @@ public function testUpgradePayload() public function testReject() { - $request = m::mock(Request::class); - $this->mockMethod('response', function () { $response = m::mock('response'); $response->shouldReceive('json') ->once() ->with([ 'code' => 3, - 'message' => 'Bad request' + 'message' => 'Bad request', ], 400); + return $response; }); $controller = new SocketIOController; - $controller->reject($request); + $controller->reject(); } protected function mockMethod($name, \Closure $function, $namespace = null) diff --git a/tests/SocketIO/WebsocketHandlerTest.php b/tests/SocketIO/WebsocketHandlerTest.php index 09575f6f..7cd011f8 100644 --- a/tests/SocketIO/WebsocketHandlerTest.php +++ b/tests/SocketIO/WebsocketHandlerTest.php @@ -2,12 +2,13 @@ namespace SwooleTW\Http\Tests\SocketIO; -use Mockery as m; -use Swoole\Websocket\Frame; + use Illuminate\Http\Request; -use SwooleTW\Http\Tests\TestCase; use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\Config; +use Mockery as m; +use Swoole\Websocket\Frame; +use SwooleTW\Http\Tests\TestCase; use SwooleTW\Http\Websocket\SocketIO\WebsocketHandler; class WebsocketHandlerTest extends TestCase @@ -31,6 +32,7 @@ public function testOnOpen() $jsonEncode = false; $this->mockMethod('json_encode', function () use (&$jsonEncode) { $jsonEncode = true; + return '{foo: "bar"}'; }, 'SwooleTW\Http\Websocket\SocketIO'); diff --git a/tests/Table/TableTest.php b/tests/Table/TableTest.php index 35efc296..7e35a6e4 100644 --- a/tests/Table/TableTest.php +++ b/tests/Table/TableTest.php @@ -2,10 +2,11 @@ namespace SwooleTW\Http\Tests\Table; + use Mockery as m; use Swoole\Table; -use SwooleTW\Http\Tests\TestCase; use SwooleTW\Http\Table\SwooleTable; +use SwooleTW\Http\Tests\TestCase; class TableTest extends TestCase { diff --git a/tests/Task/FakeJob.php b/tests/Task/FakeJob.php index 49b6ab5f..37f953b9 100644 --- a/tests/Task/FakeJob.php +++ b/tests/Task/FakeJob.php @@ -2,10 +2,11 @@ namespace SwooleTW\Http\Tests\Task; + use Illuminate\Bus\Queueable; -use Illuminate\Queue\SerializesModels; -use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Queue\InteractsWithQueue; +use Illuminate\Queue\SerializesModels; class FakeJob implements ShouldQueue { diff --git a/tests/Task/QueueFactoryTest.php b/tests/Task/QueueFactoryTest.php new file mode 100644 index 00000000..4afc0e51 --- /dev/null +++ b/tests/Task/QueueFactoryTest.php @@ -0,0 +1,58 @@ +=') ? '5.7' : '5.6'; + $stub = QueueFactory::stub($version); + + $this->assertTrue(Str::contains($stub, $search)); + } + + public function testItCanCompareNeededStubByVersion() + { + $version = '5.6'; + $search = '5.7'; + + $stub = QueueFactory::stub($version); + + $this->assertNotTrue(Str::contains($stub, $search)); + } + + public function testItCanMakeNeededQueueByVersion() + { + $version = FW::version(); + + $server = $this->getServer(); + $queue = QueueFactory::make($server, $version); + + $this->assertInstanceOf(QueueFactory::QUEUE_CLASS, $queue); + } + + protected function getServer() + { + $server = m::mock('server'); +// $server->shouldReceive('on'); + $server->taskworker = false; + $server->master_pid = -1; + + return $server; + } +} \ No newline at end of file diff --git a/tests/Task/SwooleJobTest.php b/tests/Task/SwooleJobTest.php index 7171e1ff..98fc5c23 100644 --- a/tests/Task/SwooleJobTest.php +++ b/tests/Task/SwooleJobTest.php @@ -2,10 +2,11 @@ namespace SwooleTW\Http\Tests\Task; -use Mockery as m; -use SwooleTW\Http\Tests\TestCase; + use Illuminate\Container\Container; +use Mockery as m; use SwooleTW\Http\Task\SwooleTaskJob; +use SwooleTW\Http\Tests\TestCase; class SwooleJobTest extends TestCase { diff --git a/tests/Task/SwooleQueueTest.php b/tests/Task/SwooleQueueTest.php index fecbc734..bb3fcf23 100644 --- a/tests/Task/SwooleQueueTest.php +++ b/tests/Task/SwooleQueueTest.php @@ -2,17 +2,18 @@ namespace SwooleTW\Http\Tests\Task; + use Mockery as m; +use SwooleTW\Http\Helpers\FW; +use SwooleTW\Http\Task\QueueFactory; use SwooleTW\Http\Tests\TestCase; -use SwooleTW\Http\Task\SwooleTaskQueue; class SwooleQueueTest extends TestCase { public function testPushProperlyPushesJobOntoSwoole() { $server = $this->getServer(); - - $queue = new SwooleTaskQueue($server); + $queue = QueueFactory::make($server, FW::version()); $server->shouldReceive('task')->once(); $queue->push(new FakeJob); } diff --git a/tests/TestCase.php b/tests/TestCase.php index 9d2ff71a..0965d984 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -2,12 +2,13 @@ namespace SwooleTW\Http\Tests; + +use Illuminate\Support\Facades\Facade; use Mockery as m; use phpmock\Mock; use phpmock\MockBuilder; -use SwooleTW\Http\Coroutine\Context; -use Illuminate\Support\Facades\Facade; use PHPUnit\Framework\TestCase as BaseTestCase; +use SwooleTW\Http\Coroutine\Context; class TestCase extends BaseTestCase { @@ -28,8 +29,8 @@ protected function mockMethod($name, \Closure $function, $namespace = null) { $builder = new MockBuilder(); $builder->setNamespace($namespace) - ->setName($name) - ->setFunction($function); + ->setName($name) + ->setFunction($function); $mock = $builder->build(); $mock->enable(); diff --git a/tests/Transformers/RequestTest.php b/tests/Transformers/RequestTest.php index 226ffa40..d68555d1 100644 --- a/tests/Transformers/RequestTest.php +++ b/tests/Transformers/RequestTest.php @@ -2,11 +2,12 @@ namespace SwooleTW\Http\Tests\Transformers; + +use Illuminate\Http\Request as IlluminateRequest; use Mockery as m; +use Swoole\Http\Request as SwooleRequest; use SwooleTW\Http\Tests\TestCase; use SwooleTW\Http\Transformers\Request; -use Swoole\Http\Request as SwooleRequest; -use Illuminate\Http\Request as IlluminateRequest; class RequestTest extends TestCase { @@ -34,12 +35,14 @@ public function testHandleStatic() $fileSize = false; $this->mockMethod('filesize', function () use (&$fileSize) { $fileSize = true; + return 1; }); $mimeContentType = false; $this->mockMethod('mime_content_type', function () use (&$mimeContentType) { $mimeContentType = true; + return 'foo'; }); @@ -74,6 +77,7 @@ public function testHandleStaticWithNoneFile() $isFile = false; $this->mockMethod('is_file', function () use (&$isFile) { $isFile = true; + return false; }); @@ -91,17 +95,23 @@ protected function mockMethod($name, \Closure $function, $namespace = null) class SwooleRequestStub extends SwooleRequest { public $get = []; + public $post = []; + public $header = ['foo' => 'bar']; + public $server = [ 'HTTP_CONTENT_LENGTH' => 0, 'CONTENT_LENGTH' => 0, 'HTTP_CONTENT_TYPE' => null, 'CONTENT_TYPE' => null, - 'request_uri' => 'foo.bar' + 'request_uri' => 'foo.bar', ]; + public $cookie = []; + public $files = []; + public $fd = 1; function rawContent() diff --git a/tests/Transformers/ResponseTest.php b/tests/Transformers/ResponseTest.php index d25084e5..3a2c268d 100644 --- a/tests/Transformers/ResponseTest.php +++ b/tests/Transformers/ResponseTest.php @@ -2,10 +2,11 @@ namespace SwooleTW\Http\Tests\Transformers; + +use Illuminate\Http\Response as IlluminateResponse; +use Swoole\Http\Response as SwooleResponse; use SwooleTW\Http\Tests\TestCase; use SwooleTW\Http\Transformers\Response; -use Swoole\Http\Response as SwooleResponse; -use Illuminate\Http\Response as IlluminateResponse; class ResponseTest extends TestCase { diff --git a/tests/Websocket/Middleware/AuthenticateTest.php b/tests/Websocket/Middleware/AuthenticateTest.php index 95abf43a..7f24acd1 100644 --- a/tests/Websocket/Middleware/AuthenticateTest.php +++ b/tests/Websocket/Middleware/AuthenticateTest.php @@ -2,10 +2,11 @@ namespace SwooleTW\Http\Tests\Websocket\Middleware; -use Mockery as m; + +use Illuminate\Contracts\Auth\Factory as Auth; use Illuminate\Http\Request; +use Mockery as m; use SwooleTW\Http\Tests\TestCase; -use Illuminate\Contracts\Auth\Factory as Auth; use SwooleTW\Http\Websocket\Middleware\Authenticate; class AuthenticateTest extends TestCase diff --git a/tests/Websocket/Middleware/DecrpytCookiesTest.php b/tests/Websocket/Middleware/DecrpytCookiesTest.php index e9f8913d..586f171e 100644 --- a/tests/Websocket/Middleware/DecrpytCookiesTest.php +++ b/tests/Websocket/Middleware/DecrpytCookiesTest.php @@ -2,12 +2,13 @@ namespace SwooleTW\Http\Tests\Websocket\Middleware; -use Mockery as m; + +use Illuminate\Contracts\Encryption\Encrypter as EncrypterContract; use Illuminate\Http\Request; +use Mockery as m; use SwooleTW\Http\Tests\TestCase; -use Symfony\Component\HttpFoundation\ParameterBag; use SwooleTW\Http\Websocket\Middleware\DecryptCookies; -use Illuminate\Contracts\Encryption\Encrypter as EncrypterContract; +use Symfony\Component\HttpFoundation\ParameterBag; class DecrpytCookiesTest extends TestCase { @@ -27,8 +28,8 @@ public function testDecrypt() 'foo' => 'bar', 'seafood' => 'sasaya', 'aaa' => [ - 'bbb' => 'ccc' - ] + 'bbb' => 'ccc', + ], ]); $encrypter = m::mock(EncrypterContract::class); diff --git a/tests/Websocket/Middleware/StartSessionTest.php b/tests/Websocket/Middleware/StartSessionTest.php index ac95c708..b9d75c64 100644 --- a/tests/Websocket/Middleware/StartSessionTest.php +++ b/tests/Websocket/Middleware/StartSessionTest.php @@ -2,11 +2,8 @@ namespace SwooleTW\Http\Tests\Websocket\Middleware; -use Mockery as m; -use Illuminate\Http\Request; + use SwooleTW\Http\Tests\TestCase; -use Illuminate\Session\SessionManager; -use SwooleTW\Http\Websocket\Middleware\StartSession; class StartSessionTest extends TestCase { diff --git a/tests/Websocket/RedisRoomTest.php b/tests/Websocket/RedisRoomTest.php index 8acf0c24..ce2b3634 100644 --- a/tests/Websocket/RedisRoomTest.php +++ b/tests/Websocket/RedisRoomTest.php @@ -2,9 +2,10 @@ namespace SwooleTW\Http\Tests\Websocket; + use Mockery as m; -use SwooleTW\Http\Tests\TestCase; use Predis\Client as RedisClient; +use SwooleTW\Http\Tests\TestCase; use SwooleTW\Http\Websocket\Rooms\RedisRoom; class RedisRoomTest extends TestCase diff --git a/tests/Websocket/SimpleParserTest.php b/tests/Websocket/SimpleParserTest.php index 2ef763cd..214b3a26 100644 --- a/tests/Websocket/SimpleParserTest.php +++ b/tests/Websocket/SimpleParserTest.php @@ -2,9 +2,9 @@ namespace SwooleTW\Http\Tests\Websocket; + use Mockery as m; use Swoole\Websocket\Frame; -use Swoole\Websocket\Server; use SwooleTW\Http\Tests\TestCase; use SwooleTW\Http\Websocket\SimpleParser; @@ -18,7 +18,7 @@ public function testEncode() $parser = new SimpleParser; $this->assertSame(json_encode([ 'event' => $event, - 'data' => $data + 'data' => $data, ]), $parser->encode($event, $data)); } @@ -26,7 +26,7 @@ public function testDecode() { $payload = json_encode($data = [ 'event' => 'foo', - 'data' => 'bar' + 'data' => 'bar', ]); $frame = m::mock(Frame::class); $frame->data = $payload; diff --git a/tests/Websocket/TableRoomTest.php b/tests/Websocket/TableRoomTest.php index 4eaf412c..b2df7d3a 100644 --- a/tests/Websocket/TableRoomTest.php +++ b/tests/Websocket/TableRoomTest.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http\Tests\Websocket; + use Swoole\Table; use SwooleTW\Http\Tests\TestCase; use SwooleTW\Http\Websocket\Rooms\TableRoom; @@ -16,7 +17,7 @@ public function setUp() 'room_rows' => 4096, 'room_size' => 2048, 'client_rows' => 8192, - 'client_size' => 2048 + 'client_size' => 2048, ]; $this->tableRoom = new TableRoom($config); $this->tableRoom->prepare(); diff --git a/tests/Websocket/WebsocketTest.php b/tests/Websocket/WebsocketTest.php index 91dfceab..5341b124 100644 --- a/tests/Websocket/WebsocketTest.php +++ b/tests/Websocket/WebsocketTest.php @@ -2,17 +2,18 @@ namespace SwooleTW\Http\Tests\Websocket; -use Mockery as m; + +use Illuminate\Container\Container; +use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Http\Request; -use InvalidArgumentException; use Illuminate\Pipeline\Pipeline; -use SwooleTW\Http\Tests\TestCase; -use Illuminate\Container\Container; use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\Config; -use SwooleTW\Http\Websocket\Websocket; +use InvalidArgumentException; +use Mockery as m; +use SwooleTW\Http\Tests\TestCase; use SwooleTW\Http\Websocket\Rooms\RoomContract; -use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; +use SwooleTW\Http\Websocket\Websocket; class WebsocketTest extends TestCase { @@ -339,8 +340,8 @@ public function testEmit() 'broadcast' => $broadcast, 'assigned' => true, 'event' => $event = 'event', - 'message' => $data = 'data' - ] + 'message' => $data = 'data', + ], ]) ->once(); @@ -369,7 +370,6 @@ public function testClose() $websocket = $this->getWebsocket(); $websocket->close($fd); - } protected function getWebsocket(RoomContract $room = null, $pipeline = null) diff --git a/tests/fixtures/bootstrap/app.php b/tests/fixtures/bootstrap/app.php index a7ad3f4a..4ab5ca49 100644 --- a/tests/fixtures/bootstrap/app.php +++ b/tests/fixtures/bootstrap/app.php @@ -1,8 +1,9 @@ [ SwooleTW\Http\Tests\Fixtures\Laravel\App\Providers\TestServiceProvider::class, - ] + ], ]; diff --git a/tests/fixtures/lumen/app/providers/TestServiceProvider.php b/tests/fixtures/lumen/app/providers/TestServiceProvider.php index a76a8b4e..6441b5da 100644 --- a/tests/fixtures/lumen/app/providers/TestServiceProvider.php +++ b/tests/fixtures/lumen/app/providers/TestServiceProvider.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http\Tests\Fixtures\Lumen\App\Providers; + use Illuminate\Support\ServiceProvider; class TestServiceProvider extends ServiceProvider diff --git a/tests/fixtures/lumen/config/swoole_http.php b/tests/fixtures/lumen/config/swoole_http.php index f9fa02d9..5a9e3c08 100644 --- a/tests/fixtures/lumen/config/swoole_http.php +++ b/tests/fixtures/lumen/config/swoole_http.php @@ -21,5 +21,5 @@ ], 'providers' => [ SwooleTW\Http\Tests\Fixtures\Lumen\App\Providers\TestServiceProvider::class, - ] + ], ]; From 0e160f2133c8edb6d11015e8a2495765327b4986 Mon Sep 17 00:00:00 2001 From: Fractal Zombie Date: Wed, 19 Dec 2018 21:35:50 +0200 Subject: [PATCH 015/161] Refactoring. Removes old laravel|lumen versions. Added support for 5.6|5.7 laravel|lumen. Added to config support for hot reload (Next PR). --- src/Coroutine/Connectors/MySqlConnector.php | 1 - src/Task/SwooleTaskQueue.php | 51 ++++++++++++--------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/Coroutine/Connectors/MySqlConnector.php b/src/Coroutine/Connectors/MySqlConnector.php index ebcb052b..7082d761 100644 --- a/src/Coroutine/Connectors/MySqlConnector.php +++ b/src/Coroutine/Connectors/MySqlConnector.php @@ -26,7 +26,6 @@ class MySqlConnector extends BaseConnector */ protected function createPdoConnection($dsn, $username, $password, $options) { - //TODO I'm thinking make it out by MysqlPool return new SwoolePDO($dsn, $username, $password, $options); } diff --git a/src/Task/SwooleTaskQueue.php b/src/Task/SwooleTaskQueue.php index 2cb76603..0a28fedf 100644 --- a/src/Task/SwooleTaskQueue.php +++ b/src/Task/SwooleTaskQueue.php @@ -2,11 +2,15 @@ namespace SwooleTW\Http\Task; + use Exception; -use Swoole\Timer; -use Illuminate\Queue\Queue; use Illuminate\Contracts\Queue\Queue as QueueContract; +use Illuminate\Queue\Queue; +use Swoole\Timer; +/** + * Class SwooleTaskQueue (5.7) + */ class SwooleTaskQueue extends Queue implements QueueContract { /** @@ -19,7 +23,7 @@ class SwooleTaskQueue extends Queue implements QueueContract /** * Create Async Task instance. * - * @param \Swoole\Http\Server $swoole + * @param \Swoole\Http\Server $swoole */ public function __construct($swoole) { @@ -29,9 +33,10 @@ public function __construct($swoole) /** * Push a new job onto the queue. * - * @param string|object $job - * @param mixed $data - * @param string $queue + * @param string|object $job + * @param mixed $data + * @param string $queue + * * @return mixed */ public function push($job, $data = '', $queue = null) @@ -42,24 +47,25 @@ public function push($job, $data = '', $queue = null) /** * Push a raw payload onto the queue. * - * @param string $payload - * @param string $queue - * @param array $options + * @param string $payload + * @param string $queue + * @param array $options + * * @return mixed */ public function pushRaw($payload, $queue = null, array $options = []) { - //wiki https://wiki.swoole.com/wiki/page/134.html, task($data,$dst_worker_id), $dst_worker_id should be default -1 - return $this->swoole->task($payload, (!is_numeric($queue) || $queue < 0) ? -1 : (int)$queue); + return $this->swoole->task($payload, !is_numeric($queue) ? 1 : (int)$queue); } /** * Push a new job onto the queue after a delay. * - * @param \DateTimeInterface|\DateInterval|int $delay - * @param string|object $job - * @param mixed $data - * @param string $queue + * @param \DateTimeInterface|\DateInterval|int $delay + * @param string|object $job + * @param mixed $data + * @param string $queue + * * @return mixed */ public function later($delay, $job, $data = '', $queue = null) @@ -72,12 +78,13 @@ public function later($delay, $job, $data = '', $queue = null) /** * Create a typical, string based queue payload array. * - * @param string $job - * @param mixed $data + * @param string $job + * @param string $queue + * @param mixed $data * - * @throws Expcetion + * @throws \Exception */ - protected function createStringPayload($job, $data) + protected function createStringPayload($job, $queue, $data) { throw new Exception('Unsupported empty data'); } @@ -85,7 +92,8 @@ protected function createStringPayload($job, $data) /** * Get the size of the queue. * - * @param string $queue + * @param string $queue + * * @return int */ public function size($queue = null) @@ -96,7 +104,8 @@ public function size($queue = null) /** * Pop the next job off of the queue. * - * @param string $queue + * @param string $queue + * * @return \Illuminate\Contracts\Queue\Job|null */ public function pop($queue = null) From 9f017a02f1b045785c2e46badbdc299b49e9f93d Mon Sep 17 00:00:00 2001 From: Zachary He Date: Thu, 20 Dec 2018 17:28:54 +1100 Subject: [PATCH 016/161] Fix test cases, fix [Declaration of SwooleTW\Http\Task\SwooleTaskQueue::createStringPayload($job, $data) should be compatible with Illuminate\Queue\Queue::createStringPayload($job, $queue, $data)] --- src/Task/SwooleTaskQueue.php | 11 ++++++----- tests/Server/ManagerTest.php | 4 ++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Task/SwooleTaskQueue.php b/src/Task/SwooleTaskQueue.php index 2cb76603..e14b9fbb 100644 --- a/src/Task/SwooleTaskQueue.php +++ b/src/Task/SwooleTaskQueue.php @@ -72,12 +72,13 @@ public function later($delay, $job, $data = '', $queue = null) /** * Create a typical, string based queue payload array. * - * @param string $job - * @param mixed $data - * - * @throws Expcetion + * @param string $job + * @param string $queue + * @param mixed $data + * @return array|void + * @throws Exception */ - protected function createStringPayload($job, $data) + protected function createStringPayload($job, $queue, $data) { throw new Exception('Unsupported empty data'); } diff --git a/tests/Server/ManagerTest.php b/tests/Server/ManagerTest.php index c70c89f2..e330276e 100644 --- a/tests/Server/ManagerTest.php +++ b/tests/Server/ManagerTest.php @@ -230,6 +230,8 @@ public function testOnRequest() $response->shouldReceive('status') ->once() ->andReturnSelf(); + $response->shouldReceive('write') + ->andReturnSelf(); $response->shouldReceive('end') ->once() ->andReturnSelf(); @@ -275,6 +277,8 @@ public function testOnRequestException() $response->shouldReceive('status') ->once() ->andReturnSelf(); + $response->shouldReceive('write') + ->andReturnSelf(); $response->shouldReceive('end') ->once() ->andReturnSelf(); From fad180af0b778c239f1211bc080789cd2507d872 Mon Sep 17 00:00:00 2001 From: Zachary He Date: Thu, 20 Dec 2018 17:40:27 +1100 Subject: [PATCH 017/161] quick fix --- src/Task/SwooleTaskQueue.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Task/SwooleTaskQueue.php b/src/Task/SwooleTaskQueue.php index e14b9fbb..2cb76603 100644 --- a/src/Task/SwooleTaskQueue.php +++ b/src/Task/SwooleTaskQueue.php @@ -72,13 +72,12 @@ public function later($delay, $job, $data = '', $queue = null) /** * Create a typical, string based queue payload array. * - * @param string $job - * @param string $queue - * @param mixed $data - * @return array|void - * @throws Exception + * @param string $job + * @param mixed $data + * + * @throws Expcetion */ - protected function createStringPayload($job, $queue, $data) + protected function createStringPayload($job, $data) { throw new Exception('Unsupported empty data'); } From 4346606b0568e64f0a5daa958b1fe0a0d4bb9870 Mon Sep 17 00:00:00 2001 From: Fractal Zombie Date: Thu, 20 Dec 2018 12:55:11 +0200 Subject: [PATCH 018/161] Fix code style for PR. --- src/Commands/HttpServerCommand.php | 39 +++++++++------- src/Concerns/InteractsWithSwooleTable.php | 3 +- src/Concerns/InteractsWithWebsocket.php | 15 +++---- src/Concerns/ResetApplication.php | 7 ++- src/Concerns/WithApplication.php | 11 ++--- src/Controllers/SocketIOController.php | 41 ++++++++++------- src/Coroutine/ConnectionException.php | 1 - src/Coroutine/Connectors/ConnectorFactory.php | 11 +++-- src/Coroutine/Connectors/MySqlConnector.php | 1 - src/Coroutine/Context.php | 1 - src/Coroutine/MySqlConnection.php | 6 ++- src/Coroutine/PDO.php | 18 ++++---- src/Coroutine/PDOStatement.php | 17 ++++--- src/Coroutine/StatementException.php | 1 - .../FrameworkNotSupportException.php | 1 - src/Exceptions/SandboxException.php | 1 - .../WebsocketNotSetInConfigException.php | 2 - src/Helpers/FW.php | 1 - src/Helpers/OS.php | 1 - src/Helpers/Service.php | 1 - src/HttpServiceProvider.php | 29 +++++++----- src/LaravelServiceProvider.php | 3 +- src/LumenServiceProvider.php | 5 +-- src/Server/Facades/Sandbox.php | 1 - src/Server/Facades/Server.php | 1 - src/Server/Manager.php | 30 +++++++++---- src/Server/Resetters/BindRequest.php | 1 - src/Server/Resetters/ClearInstances.php | 1 - .../Resetters/RebindKernelContainer.php | 1 - .../Resetters/RebindRouterContainer.php | 1 - src/Server/Resetters/RebindViewContainer.php | 1 - src/Server/Resetters/ResetConfig.php | 1 - src/Server/Resetters/ResetCookie.php | 1 - src/Server/Resetters/ResetProviders.php | 1 - src/Server/Resetters/ResetSession.php | 1 - src/Server/Resetters/ResetterContract.php | 1 - src/Server/Sandbox.php | 18 +++++--- src/Server/helpers.php | 6 +-- src/Table/Facades/SwooleTable.php | 1 - src/Table/SwooleTable.php | 1 - src/Task/Connectors/SwooleTaskConnector.php | 1 - src/Task/QueueFactory.php | 11 +++-- src/Task/SwooleTaskJob.php | 1 - src/Task/SwooleTaskQueue.php | 3 +- src/Transformers/Request.php | 19 ++++---- src/Transformers/Response.php | 22 ++++++---- src/Websocket/Authenticatable.php | 15 +++---- src/Websocket/Facades/Room.php | 1 - src/Websocket/Facades/Websocket.php | 1 - src/Websocket/HandlerContract.php | 1 - src/Websocket/Middleware/Authenticate.php | 1 - src/Websocket/Middleware/DecryptCookies.php | 1 - src/Websocket/Middleware/StartSession.php | 3 +- src/Websocket/Parser.php | 12 ++--- src/Websocket/Push.php | 6 +-- src/Websocket/Rooms/RedisRoom.php | 5 +-- src/Websocket/Rooms/RoomContract.php | 1 - src/Websocket/Rooms/TableRoom.php | 14 +++--- src/Websocket/SimpleParser.php | 11 ++--- src/Websocket/SocketIO/Packet.php | 3 +- src/Websocket/SocketIO/SocketIOParser.php | 5 +-- .../SocketIO/Strategies/HeartbeatStrategy.php | 1 - src/Websocket/SocketIO/WebsocketHandler.php | 21 ++++----- src/Websocket/Websocket.php | 44 ++++++++++--------- 64 files changed, 249 insertions(+), 238 deletions(-) diff --git a/src/Commands/HttpServerCommand.php b/src/Commands/HttpServerCommand.php index 30ab626d..1bbe7582 100644 --- a/src/Commands/HttpServerCommand.php +++ b/src/Commands/HttpServerCommand.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Commands; - use Illuminate\Console\Command; use Illuminate\Support\Arr; use Swoole\Process; @@ -95,8 +94,10 @@ protected function start() $this->info('Starting swoole http server...'); $this->info("Swoole http server started: "); if ($this->isDaemon()) { - $this->info('> (You can run this command to ensure the ' . - 'swoole_http_server process is running: ps aux|grep "swoole")'); + $this->info( + '> (You can run this command to ensure the '. + 'swoole_http_server process is running: ps aux|grep "swoole")' + ); } $this->laravel->make('swoole.manager')->run(); @@ -109,7 +110,7 @@ protected function stop() { $pid = $this->getCurrentPid(); - if (!$this->isRunning($pid)) { + if (! $this->isRunning($pid)) { $this->error("Failed! There is no swoole_http_server process running."); return; @@ -153,7 +154,7 @@ protected function reload() { $pid = $this->getCurrentPid(); - if (!$this->isRunning($pid)) { + if (! $this->isRunning($pid)) { $this->error("Failed! There is no swoole_http_server process running."); return; @@ -163,7 +164,7 @@ protected function reload() $isRunning = $this->killProcess($pid, SIGUSR1); - if (!$isRunning) { + if (! $isRunning) { $this->error('> failure'); return; @@ -220,8 +221,10 @@ protected function initAction() { $this->action = $this->argument('action'); - if (!in_array($this->action, ['start', 'stop', 'restart', 'reload', 'infos'], true)) { - $this->error("Invalid argument '{$this->action}'. Expected 'start', 'stop', 'restart', 'reload' or 'infos'."); + if (! in_array($this->action, ['start', 'stop', 'restart', 'reload', 'infos'], true)) { + $this->error( + "Invalid argument '{$this->action}'. Expected 'start', 'stop', 'restart', 'reload' or 'infos'." + ); return; } @@ -236,7 +239,7 @@ protected function initAction() */ protected function isRunning($pid) { - if (!$pid) { + if (! $pid) { return false; } @@ -264,7 +267,7 @@ protected function killProcess($pid, $sig, $wait = 0) $start = time(); do { - if (!$this->isRunning($pid)) { + if (! $this->isRunning($pid)) { break; } @@ -330,14 +333,18 @@ protected function checkEnvironment() $this->error("Swoole extension doesn't support Windows OS yet."); return; - } else if (!extension_loaded('swoole')) { - $this->error("Can't detect Swoole extension installed."); + } else { + if (! extension_loaded('swoole')) { + $this->error("Can't detect Swoole extension installed."); - return; - } else if (!version_compare(swoole_version(), '4.0.0', 'ge')) { - $this->error("Your Swoole version must be higher than 4.0 to use coroutine."); + return; + } else { + if (! version_compare(swoole_version(), '4.0.0', 'ge')) { + $this->error("Your Swoole version must be higher than 4.0 to use coroutine."); - return; + return; + } + } } } } diff --git a/src/Concerns/InteractsWithSwooleTable.php b/src/Concerns/InteractsWithSwooleTable.php index aa9e1b17..eca5381f 100644 --- a/src/Concerns/InteractsWithSwooleTable.php +++ b/src/Concerns/InteractsWithSwooleTable.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Concerns; - use Illuminate\Contracts\Console\Application as ConsoleApp; use Swoole\Table; use SwooleTW\Http\Table\SwooleTable; @@ -57,7 +56,7 @@ protected function registerTables() */ protected function bindSwooleTable() { - if (!$this->app instanceof ConsoleApp) { + if (! $this->app instanceof ConsoleApp) { $this->app->singleton(SwooleTable::class, function () { return $this->currentTable; }); diff --git a/src/Concerns/InteractsWithWebsocket.php b/src/Concerns/InteractsWithWebsocket.php index 66bff107..81aa724c 100644 --- a/src/Concerns/InteractsWithWebsocket.php +++ b/src/Concerns/InteractsWithWebsocket.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Concerns; - use Illuminate\Contracts\Container\Container; use Illuminate\Pipeline\Pipeline; use Illuminate\Support\Arr; @@ -65,7 +64,7 @@ public function onOpen($swooleRequest) // enable sandbox $sandbox->enable(); // check if socket.io connection established - if (!$this->websocketHandler->onOpen($swooleRequest->fd, $illuminateRequest)) { + if (! $this->websocketHandler->onOpen($swooleRequest->fd, $illuminateRequest)) { return; } // trigger 'connect' websocket event @@ -129,7 +128,7 @@ public function onMessage($server, $frame) */ public function onClose($server, $fd, $reactorId) { - if (!$this->isServerWebsocket($fd) || !$server instanceof Websocket) { + if (! $this->isServerWebsocket($fd) || ! $server instanceof Websocket) { return; } @@ -162,7 +161,7 @@ public function pushMessage($server, array $data) $payload = $this->payloadParser->encode($push->getEvent(), $push->getMessage()); // attach sender if not broadcast - if (!$push->isBroadcast() && $push->getSender() && !$push->hasOwnDescriptor()) { + if (! $push->isBroadcast() && $push->getSender() && ! $push->hasOwnDescriptor()) { $push->addDescriptor($push->getSender()); } @@ -173,7 +172,7 @@ public function pushMessage($server, array $data) // push message to designated fds foreach ($push->getDescriptors() as $descriptor) { - if ($server->exist($descriptor) || !$push->isBroadcastToDescriptor((int)$descriptor)) { + if ($server->exist($descriptor) || ! $push->isBroadcastToDescriptor((int)$descriptor)) { $server->push($descriptor, $payload, $push->getOpcode()); } } @@ -256,7 +255,7 @@ protected function prepareWebsocketHandler() { $handlerClass = $this->container->make(Service::CONFIG_ALIAS)->get('swoole_websocket.handler'); - if (!$handlerClass) { + if (! $handlerClass) { throw new WebsocketNotSetInConfigException; } @@ -334,8 +333,8 @@ protected function loadWebsocketRoutes() { $routePath = $this->container->make(Service::CONFIG_ALIAS)->get('swoole_websocket.route_file'); - if (!file_exists($routePath)) { - $routePath = __DIR__ . '/../../routes/websocket.php'; + if (! file_exists($routePath)) { + $routePath = __DIR__.'/../../routes/websocket.php'; } return require $routePath; diff --git a/src/Concerns/ResetApplication.php b/src/Concerns/ResetApplication.php index 4e611a3e..a6c96c01 100644 --- a/src/Concerns/ResetApplication.php +++ b/src/Concerns/ResetApplication.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Concerns; - use Illuminate\Contracts\Container\Container; use SwooleTW\Http\Exceptions\SandboxException; use SwooleTW\Http\Server\Resetters\ResetterContract; @@ -49,7 +48,7 @@ protected function setInitialProviders() $providers = $this->config->get('swoole_http.providers', []); foreach ($providers as $provider) { - if (class_exists($provider) && !in_array($provider, $this->providers)) { + if (class_exists($provider) && ! in_array($provider, $this->providers)) { $providerClass = new $provider($app); $this->providers[$provider] = $providerClass; } @@ -74,8 +73,8 @@ protected function setInitialResetters() foreach ($resetters as $resetter) { $resetterClass = $app->make($resetter); - if (!$resetterClass instanceof ResetterContract) { - throw new SandboxException("{$resetter} must implement " . ResetterContract::class); + if (! $resetterClass instanceof ResetterContract) { + throw new SandboxException("{$resetter} must implement ".ResetterContract::class); } $this->resetters[$resetter] = $resetterClass; } diff --git a/src/Concerns/WithApplication.php b/src/Concerns/WithApplication.php index 46053cbf..8aa54ec4 100644 --- a/src/Concerns/WithApplication.php +++ b/src/Concerns/WithApplication.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Concerns; - use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Http\Kernel; use Illuminate\Support\Facades\Facade; @@ -34,8 +33,10 @@ protected function bootstrap() if ($this->framework === 'laravel') { $bootstrappers = $this->getBootstrappers(); $this->app->bootstrapWith($bootstrappers); - } else if (is_null(Facade::getFacadeApplication())) { - $this->app->withFacades(); + } else { + if (is_null(Facade::getFacadeApplication())) { + $this->app->withFacades(); + } } $this->preResolveInstances(); @@ -57,7 +58,7 @@ protected function loadApplication() */ public function getApplication() { - if (!$this->app instanceof Container) { + if (! $this->app instanceof Container) { $this->app = $this->loadApplication(); $this->bootstrap(); } @@ -108,7 +109,7 @@ protected function setFramework($framework) { $framework = strtolower($framework); - if (!in_array($framework, ['laravel', 'lumen'])) { + if (! in_array($framework, ['laravel', 'lumen'])) { throw new FrameworkNotSupportException($framework); } diff --git a/src/Controllers/SocketIOController.php b/src/Controllers/SocketIOController.php index 48819983..321aed94 100644 --- a/src/Controllers/SocketIOController.php +++ b/src/Controllers/SocketIOController.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Controllers; - use Illuminate\Http\Request; use Illuminate\Support\Facades\Config; @@ -12,32 +11,40 @@ class SocketIOController public function upgrade(Request $request) { - if (!in_array($request->input('transport'), $this->transports)) { - return response()->json([ - 'code' => 0, - 'message' => 'Transport unknown', - ], 400); + if (! in_array($request->input('transport'), $this->transports)) { + return response()->json( + [ + 'code' => 0, + 'message' => 'Transport unknown', + ], + 400 + ); } if ($request->has('sid')) { return '1:6'; } - $payload = json_encode([ - 'sid' => base64_encode(uniqid()), - 'upgrades' => ['websocket'], - 'pingInterval' => Config::get('swoole_websocket.ping_interval'), - 'pingTimeout' => Config::get('swoole_websocket.ping_timeout'), - ]); + $payload = json_encode( + [ + 'sid' => base64_encode(uniqid()), + 'upgrades' => ['websocket'], + 'pingInterval' => Config::get('swoole_websocket.ping_interval'), + 'pingTimeout' => Config::get('swoole_websocket.ping_timeout'), + ] + ); - return '97:0' . $payload . '2:40'; + return '97:0'.$payload.'2:40'; } public function reject() { - return response()->json([ - 'code' => 3, - 'message' => 'Bad request', - ], 400); + return response()->json( + [ + 'code' => 3, + 'message' => 'Bad request', + ], + 400 + ); } } diff --git a/src/Coroutine/ConnectionException.php b/src/Coroutine/ConnectionException.php index 1698f80b..f5ae28c0 100644 --- a/src/Coroutine/ConnectionException.php +++ b/src/Coroutine/ConnectionException.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Coroutine; - class ConnectionException extends \Exception { // diff --git a/src/Coroutine/Connectors/ConnectorFactory.php b/src/Coroutine/Connectors/ConnectorFactory.php index 37dcb51a..32f6e437 100644 --- a/src/Coroutine/Connectors/ConnectorFactory.php +++ b/src/Coroutine/Connectors/ConnectorFactory.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Coroutine\Connectors; - use Illuminate\Support\Arr; use SwooleTW\Http\Helpers\FW; @@ -30,7 +29,7 @@ class ConnectorFactory * * @const string */ - public const CONNECTOR_CLASS_PATH = __DIR__ . '/MySqlConnector.php'; + public const CONNECTOR_CLASS_PATH = __DIR__.'/MySqlConnector.php'; /** * @param string $version @@ -40,7 +39,7 @@ class ConnectorFactory public static function make(string $version): MySqlConnector { $isMatch = static::isFileVersionMatch($version); - $class = static::copy(static::stub($version), !$isMatch); + $class = static::copy(static::stub($version), ! $isMatch); return new $class(); } @@ -53,8 +52,8 @@ public static function make(string $version): MySqlConnector public static function stub(string $version): string { return static::hasBreakingChanges($version) - ? __DIR__ . '/../../../stubs/5.6/MySqlConnector.stub' - : __DIR__ . '/../../../stubs/5.5/MySqlConnector.stub'; + ? __DIR__.'/../../../stubs/5.6/MySqlConnector.stub' + : __DIR__.'/../../../stubs/5.5/MySqlConnector.stub'; } /** @@ -65,7 +64,7 @@ public static function stub(string $version): string */ public static function copy(string $stub, bool $rewrite = false): string { - if (!file_exists(static::CONNECTOR_CLASS_PATH) || $rewrite) { + if (! file_exists(static::CONNECTOR_CLASS_PATH) || $rewrite) { copy($stub, static::CONNECTOR_CLASS_PATH); } diff --git a/src/Coroutine/Connectors/MySqlConnector.php b/src/Coroutine/Connectors/MySqlConnector.php index 7082d761..2efa720a 100644 --- a/src/Coroutine/Connectors/MySqlConnector.php +++ b/src/Coroutine/Connectors/MySqlConnector.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Coroutine\Connectors; - use Illuminate\Database\Connectors\MySqlConnector as BaseConnector; use Illuminate\Support\Str; use SwooleTW\Http\Coroutine\PDO as SwoolePDO; diff --git a/src/Coroutine/Context.php b/src/Coroutine/Context.php index 9f118229..2ea8a20c 100644 --- a/src/Coroutine/Context.php +++ b/src/Coroutine/Context.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Coroutine; - use Illuminate\Contracts\Container\Container; use Swoole\Coroutine; diff --git a/src/Coroutine/MySqlConnection.php b/src/Coroutine/MySqlConnection.php index 27e972b5..631ad6bb 100644 --- a/src/Coroutine/MySqlConnection.php +++ b/src/Coroutine/MySqlConnection.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Coroutine; - use Closure; use Illuminate\Database\MySqlConnection as BaseConnection; use Illuminate\Database\QueryException; @@ -25,7 +24,10 @@ class MySqlConnection extends BaseConnection protected function tryAgainIfCausedByLostConnection(QueryException $e, $query, $bindings, Closure $callback) { // https://github.com/swoole/swoole-src/blob/a414e5e8fec580abb3dbd772d483e12976da708f/swoole_mysql_coro.c#L1140 - if ($this->causedByLostConnection($e->getPrevious()) || Str::contains($e->getMessage(), ['is closed', 'is not established'])) { + if ($this->causedByLostConnection($e->getPrevious()) || Str::contains( + $e->getMessage(), + ['is closed', 'is not established'] + )) { $this->reconnect(); return $this->runQueryCallback($query, $bindings, $callback); diff --git a/src/Coroutine/PDO.php b/src/Coroutine/PDO.php index c79e2af9..54e44972 100644 --- a/src/Coroutine/PDO.php +++ b/src/Coroutine/PDO.php @@ -9,7 +9,6 @@ namespace SwooleTW\Http\Coroutine; - use Exception; use Illuminate\Database\QueryException; use Illuminate\Support\Arr; @@ -75,7 +74,7 @@ protected function connect(array $options = []) { $this->client->connect($options); - if (!$this->client->connected) { + if (! $this->client->connected) { $message = $this->client->connect_error ?: $this->client->error; $errorCode = $this->client->connect_errno ?: $this->client->errno; @@ -131,7 +130,7 @@ protected function getOptions($dsn, $username, $password, $driverOptions) */ public static function checkDriver(string $driver) { - if (!in_array($driver, static::getAvailableDrivers())) { + if (! in_array($driver, static::getAvailableDrivers())) { throw new \InvalidArgumentException("{$driver} driver is not supported yet."); } } @@ -253,13 +252,11 @@ public function prepare($statement, $options = null) if (strpos($statement, ':') !== false) { $i = 0; $bindKeyMap = []; - $statement = preg_replace_callback( - '/:([a-zA-Z_]\w*?)\b/', - function ($matches) use (&$i, &$bindKeyMap) { - $bindKeyMap[$matches[1]] = $i++; + $statement = preg_replace_callback('/:([a-zA-Z_]\w*?)\b/', function ($matches) use (&$i, &$bindKeyMap) { + $bindKeyMap[$matches[1]] = $i++; - return '?'; - }, $statement); + return '?'; + }, $statement); } $stmtObj = $this->client->prepare($statement); @@ -312,7 +309,8 @@ public function getAttribute($attribute) */ public function quote($string, $paramtype = null) { - throw new \BadMethodCallException(<<resultSet = ($ok = $result !== false) ? $result : []; $this->afterExecute(); - if ($result === false){ + if ($result === false) { throw new \PDOException($this->errorInfo(), $this->errorCode()); } @@ -172,7 +178,7 @@ private function transStyle( break; case PDO::FETCH_OBJ: foreach ($rawData as $row) { - $resultSet[] = (object) $row; + $resultSet[] = (object)$row; } break; case PDO::FETCH_NUM: @@ -197,7 +203,7 @@ public function fetch( $this->__executeWhenStringQueryEmpty(); $cursorOrientation = is_null($cursorOrientation) ? PDO::FETCH_ORI_NEXT : $cursorOrientation; - $cursorOffset = is_null($cursorOffset) ? 0 : (int) $cursorOffset; + $cursorOffset = is_null($cursorOffset) ? 0 : (int)$cursorOffset; switch ($cursorOrientation) { case PDO::FETCH_ORI_ABS: @@ -238,6 +244,7 @@ public function fetchColumn($columnNumber = null) { $columnNumber = is_null($columnNumber) ? 0 : $columnNumber; $this->__executeWhenStringQueryEmpty(); + return $this->fetch(PDO::FETCH_COLUMN, PDO::FETCH_ORI_NEXT, 0, $columnNumber); } diff --git a/src/Coroutine/StatementException.php b/src/Coroutine/StatementException.php index 9259bcbd..ca839e08 100644 --- a/src/Coroutine/StatementException.php +++ b/src/Coroutine/StatementException.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Coroutine; - class StatementException extends \Exception { // diff --git a/src/Exceptions/FrameworkNotSupportException.php b/src/Exceptions/FrameworkNotSupportException.php index 90401358..f393279c 100644 --- a/src/Exceptions/FrameworkNotSupportException.php +++ b/src/Exceptions/FrameworkNotSupportException.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Exceptions; - /** * Class FrameworkNotSupportException */ diff --git a/src/Exceptions/SandboxException.php b/src/Exceptions/SandboxException.php index 1626ebd0..9a124ef3 100644 --- a/src/Exceptions/SandboxException.php +++ b/src/Exceptions/SandboxException.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Exceptions; - use Exception; class SandboxException extends Exception diff --git a/src/Exceptions/WebsocketNotSetInConfigException.php b/src/Exceptions/WebsocketNotSetInConfigException.php index 3d5f21d5..b5285d63 100644 --- a/src/Exceptions/WebsocketNotSetInConfigException.php +++ b/src/Exceptions/WebsocketNotSetInConfigException.php @@ -2,9 +2,7 @@ namespace SwooleTW\Http\Exceptions; - use Exception; -use Throwable; class WebsocketNotSetInConfigException extends Exception { diff --git a/src/Helpers/FW.php b/src/Helpers/FW.php index d85ed4b8..238f7ec5 100644 --- a/src/Helpers/FW.php +++ b/src/Helpers/FW.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Helpers; - use Illuminate\Support\Arr; use LogicException; diff --git a/src/Helpers/OS.php b/src/Helpers/OS.php index 1104473b..8f33cde7 100644 --- a/src/Helpers/OS.php +++ b/src/Helpers/OS.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Helpers; - use Illuminate\Support\Str; /** diff --git a/src/Helpers/Service.php b/src/Helpers/Service.php index 06505638..5fa972e6 100644 --- a/src/Helpers/Service.php +++ b/src/Helpers/Service.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Helpers; - /** * Class Service */ diff --git a/src/HttpServiceProvider.php b/src/HttpServiceProvider.php index cb9f82b6..071291ca 100644 --- a/src/HttpServiceProvider.php +++ b/src/HttpServiceProvider.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http; - use Illuminate\Queue\Capsule\Manager; use Illuminate\Support\ServiceProvider; use Swoole\Http\Server as HttpServer; @@ -74,11 +73,14 @@ abstract protected function bootRoutes(); */ public function boot() { - $this->publishes([ - __DIR__ . '/../config/swoole_http.php' => base_path('config/swoole_http.php'), - __DIR__ . '/../config/swoole_websocket.php' => base_path('config/swoole_websocket.php'), - __DIR__ . '/../routes/websocket.php' => base_path('routes/websocket.php'), - ], 'laravel-swoole'); + $this->publishes( + [ + __DIR__.'/../config/swoole_http.php' => base_path('config/swoole_http.php'), + __DIR__.'/../config/swoole_websocket.php' => base_path('config/swoole_websocket.php'), + __DIR__.'/../routes/websocket.php' => base_path('routes/websocket.php'), + ], + 'laravel-swoole' + ); if ($this->app->make(Service::CONFIG_ALIAS)->get('swoole_http.websocket.enabled')) { $this->bootRoutes(); @@ -90,8 +92,8 @@ public function boot() */ protected function mergeConfigs() { - $this->mergeConfigFrom(__DIR__ . '/../config/swoole_http.php', 'swoole_http'); - $this->mergeConfigFrom(__DIR__ . '/../config/swoole_websocket.php', 'swoole_websocket'); + $this->mergeConfigFrom(__DIR__.'/../config/swoole_http.php', 'swoole_http'); + $this->mergeConfigFrom(__DIR__.'/../config/swoole_websocket.php', 'swoole_websocket'); } /** @@ -107,9 +109,11 @@ protected function setIsWebsocket() */ protected function registerCommands() { - $this->commands([ - HttpServerCommand::class, - ]); + $this->commands( + [ + HttpServerCommand::class, + ] + ); } /** @@ -136,7 +140,7 @@ protected function configureSwooleServer() $options = $config->get('swoole_http.server.options'); // only enable task worker in websocket mode and for queue driver - if ($config->get('queue.default') !== 'swoole' && !$this->isWebsocket) { + if ($config->get('queue.default') !== 'swoole' && ! $this->isWebsocket) { unset($config['task_worker_num']); } @@ -158,6 +162,7 @@ protected function registerServer() return static::$server; }); + $this->app->alias(Server::class, Service::SERVER_ALIAS); } diff --git a/src/LaravelServiceProvider.php b/src/LaravelServiceProvider.php index fe35a3ce..5cf86a30 100644 --- a/src/LaravelServiceProvider.php +++ b/src/LaravelServiceProvider.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http; - use SwooleTW\Http\Server\Manager; /** @@ -29,6 +28,6 @@ protected function registerManager() */ protected function bootRoutes() { - require __DIR__ . '/../routes/laravel_routes.php'; + require __DIR__.'/../routes/laravel_routes.php'; } } diff --git a/src/LumenServiceProvider.php b/src/LumenServiceProvider.php index 8e1bdfa9..40f218b4 100644 --- a/src/LumenServiceProvider.php +++ b/src/LumenServiceProvider.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http; - use SwooleTW\Http\Server\Manager; /** @@ -33,11 +32,11 @@ protected function bootRoutes() if (property_exists($app, 'router')) { $app->router->group(['namespace' => 'SwooleTW\Http\Controllers'], function ($app) { - require __DIR__ . '/../routes/lumen_routes.php'; + require __DIR__.'/../routes/lumen_routes.php'; }); } else { $app->group(['namespace' => 'App\Http\Controllers'], function ($app) { - require __DIR__ . '/../routes/lumen_routes.php'; + require __DIR__.'/../routes/lumen_routes.php'; }); } } diff --git a/src/Server/Facades/Sandbox.php b/src/Server/Facades/Sandbox.php index 6375ecbb..8c468254 100644 --- a/src/Server/Facades/Sandbox.php +++ b/src/Server/Facades/Sandbox.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Server\Facades; - use Illuminate\Support\Facades\Facade; class Sandbox extends Facade diff --git a/src/Server/Facades/Server.php b/src/Server/Facades/Server.php index 8fc3e2b3..7a34102a 100644 --- a/src/Server/Facades/Server.php +++ b/src/Server/Facades/Server.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Server\Facades; - use Illuminate\Support\Facades\Facade; class Server extends Facade diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 695362b6..3eb47bb1 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Server; - use Exception; use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Debug\ExceptionHandler; @@ -51,9 +50,20 @@ class Manager * @var array */ protected $events = [ - 'start', 'shutDown', 'workerStart', 'workerStop', 'packet', - 'bufferFull', 'bufferEmpty', 'task', 'finish', 'pipeMessage', - 'workerError', 'managerStart', 'managerStop', 'request', + 'start', + 'shutDown', + 'workerStart', + 'workerStop', + 'packet', + 'bufferFull', + 'bufferEmpty', + 'task', + 'finish', + 'pipeMessage', + 'workerError', + 'managerStart', + 'managerStop', + 'request', ]; /** @@ -250,11 +260,13 @@ public function onTask($server, $taskId, $srcWorkerId, $data) $this->pushMessage($server, $data['data'] ?? []); } // push async task to queue - } else if (is_string($data)) { - $decoded = \json_decode($data, true); + } else { + if (is_string($data)) { + $decoded = \json_decode($data, true); - if (JSON_ERROR_NONE === \json_last_error() && isset($decoded['job'])) { - (new SwooleTaskJob($this->container, $server, $data, $taskId, $srcWorkerId))->fire(); + if (JSON_ERROR_NONE === \json_last_error() && isset($decoded['job'])) { + (new SwooleTaskJob($this->container, $server, $data, $taskId, $srcWorkerId))->fire(); + } } } } catch (Throwable $e) { @@ -396,7 +408,7 @@ protected function isInTesting() */ public function logServerError(Throwable $e) { - if (!$e instanceof Exception) { + if (! $e instanceof Exception) { $e = new FatalThrowableError($e); } diff --git a/src/Server/Resetters/BindRequest.php b/src/Server/Resetters/BindRequest.php index 610329c9..b0787829 100644 --- a/src/Server/Resetters/BindRequest.php +++ b/src/Server/Resetters/BindRequest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Server\Resetters; - use Illuminate\Contracts\Container\Container; use Illuminate\Http\Request; use SwooleTW\Http\Server\Sandbox; diff --git a/src/Server/Resetters/ClearInstances.php b/src/Server/Resetters/ClearInstances.php index 9d0d446c..865516f1 100644 --- a/src/Server/Resetters/ClearInstances.php +++ b/src/Server/Resetters/ClearInstances.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Server\Resetters; - use Illuminate\Contracts\Container\Container; use SwooleTW\Http\Server\Sandbox; diff --git a/src/Server/Resetters/RebindKernelContainer.php b/src/Server/Resetters/RebindKernelContainer.php index 7a8187be..f2d8b9b4 100644 --- a/src/Server/Resetters/RebindKernelContainer.php +++ b/src/Server/Resetters/RebindKernelContainer.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Server\Resetters; - use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Http\Kernel; use SwooleTW\Http\Server\Sandbox; diff --git a/src/Server/Resetters/RebindRouterContainer.php b/src/Server/Resetters/RebindRouterContainer.php index ca6151ed..15274195 100644 --- a/src/Server/Resetters/RebindRouterContainer.php +++ b/src/Server/Resetters/RebindRouterContainer.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Server\Resetters; - use Illuminate\Contracts\Container\Container; use SwooleTW\Http\Server\Sandbox; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; diff --git a/src/Server/Resetters/RebindViewContainer.php b/src/Server/Resetters/RebindViewContainer.php index 3f1cb57f..525f9daa 100644 --- a/src/Server/Resetters/RebindViewContainer.php +++ b/src/Server/Resetters/RebindViewContainer.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Server\Resetters; - use Illuminate\Contracts\Container\Container; use SwooleTW\Http\Server\Sandbox; diff --git a/src/Server/Resetters/ResetConfig.php b/src/Server/Resetters/ResetConfig.php index 4a0356c8..24cea3aa 100644 --- a/src/Server/Resetters/ResetConfig.php +++ b/src/Server/Resetters/ResetConfig.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Server\Resetters; - use Illuminate\Contracts\Container\Container; use SwooleTW\Http\Server\Sandbox; diff --git a/src/Server/Resetters/ResetCookie.php b/src/Server/Resetters/ResetCookie.php index 2d89cf44..85da6cba 100644 --- a/src/Server/Resetters/ResetCookie.php +++ b/src/Server/Resetters/ResetCookie.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Server\Resetters; - use Illuminate\Contracts\Container\Container; use SwooleTW\Http\Server\Sandbox; diff --git a/src/Server/Resetters/ResetProviders.php b/src/Server/Resetters/ResetProviders.php index f232f9d8..0193106b 100644 --- a/src/Server/Resetters/ResetProviders.php +++ b/src/Server/Resetters/ResetProviders.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Server\Resetters; - use Illuminate\Contracts\Container\Container; use SwooleTW\Http\Server\Sandbox; diff --git a/src/Server/Resetters/ResetSession.php b/src/Server/Resetters/ResetSession.php index 3848d55d..9a97ac53 100644 --- a/src/Server/Resetters/ResetSession.php +++ b/src/Server/Resetters/ResetSession.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Server\Resetters; - use Illuminate\Contracts\Container\Container; use SwooleTW\Http\Server\Sandbox; diff --git a/src/Server/Resetters/ResetterContract.php b/src/Server/Resetters/ResetterContract.php index e6398751..27a5d85c 100644 --- a/src/Server/Resetters/ResetterContract.php +++ b/src/Server/Resetters/ResetterContract.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Server\Resetters; - use Illuminate\Contracts\Container\Container; use SwooleTW\Http\Server\Sandbox; diff --git a/src/Server/Sandbox.php b/src/Server/Sandbox.php index 1ab2041b..ccf0f74c 100644 --- a/src/Server/Sandbox.php +++ b/src/Server/Sandbox.php @@ -2,18 +2,18 @@ namespace SwooleTW\Http\Server; -use Illuminate\Http\Request; use Illuminate\Container\Container; -use SwooleTW\Http\Coroutine\Context; +use Illuminate\Contracts\Config\Repository as ConfigContract; use Illuminate\Contracts\Http\Kernel; +use Illuminate\Http\Request; use Illuminate\Support\Facades\Facade; +use Laravel\Lumen\Application as LumenApplication; use SwooleTW\Http\Concerns\ResetApplication; +use SwooleTW\Http\Coroutine\Context; use SwooleTW\Http\Exceptions\SandboxException; -use Laravel\Lumen\Application as LumenApplication; -use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpFoundation\BinaryFileResponse; -use Illuminate\Contracts\Config\Repository as ConfigContract; use Symfony\Component\HttpFoundation\Response as SymfonyResponse; +use Symfony\Component\HttpFoundation\StreamedResponse; class Sandbox { @@ -145,6 +145,7 @@ public function getApplication() * Run framework. * * @param \Illuminate\Http\Request $request + * * @return \Illuminate\Http\Response */ public function run(Request $request) @@ -166,6 +167,7 @@ public function run(Request $request) * Handle request for non-ob case. * * @param \Illuminate\Http\Request $request + * * @return \Illuminate\Http\Response */ protected function prepareResponse(Request $request) @@ -183,6 +185,7 @@ protected function prepareResponse(Request $request) * Handle request for ob output. * * @param \Illuminate\Http\Request $request + * * @return \Illuminate\Http\Response */ protected function prepareObResponse(Request $request) @@ -200,7 +203,7 @@ protected function prepareObResponse(Request $request) } elseif ($response instanceof SymfonyResponse) { $content = $response->getContent(); } elseif (! $isFile = $response instanceof BinaryFileResponse) { - $content = (string) $response; + $content = (string)$response; } // process terminating logics @@ -211,7 +214,7 @@ protected function prepareObResponse(Request $request) if ($isStream) { $response->output = ob_get_contents(); } else { - $response->setContent(ob_get_contents() . $content); + $response->setContent(ob_get_contents().$content); } } @@ -224,6 +227,7 @@ protected function prepareObResponse(Request $request) * Handle request through Laravel or Lumen. * * @param \Illuminate\Http\Request $request + * * @return \Illuminate\Http\Response */ protected function handleRequest(Request $request) diff --git a/src/Server/helpers.php b/src/Server/helpers.php index 624043bc..51dd9fcb 100644 --- a/src/Server/helpers.php +++ b/src/Server/helpers.php @@ -3,7 +3,7 @@ /** * This is only for `function not exists` in config/swoole_http.php. */ -if (!function_exists('swoole_cpu_num')) { +if (! function_exists('swoole_cpu_num')) { function swoole_cpu_num(): int { return 1; @@ -13,10 +13,10 @@ function swoole_cpu_num(): int /** * This is only for `function not exists` in config/swoole_http.php. */ -if (!defined('SWOOLE_SOCK_TCP')) { +if (! defined('SWOOLE_SOCK_TCP')) { define('SWOOLE_SOCK_TCP', 1); } -if (!defined('SWOOLE_PROCESS')) { +if (! defined('SWOOLE_PROCESS')) { define('SWOOLE_PROCESS', 3); } diff --git a/src/Table/Facades/SwooleTable.php b/src/Table/Facades/SwooleTable.php index fb89a85b..e9f9de11 100644 --- a/src/Table/Facades/SwooleTable.php +++ b/src/Table/Facades/SwooleTable.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Table\Facades; - use Illuminate\Support\Facades\Facade; /** diff --git a/src/Table/SwooleTable.php b/src/Table/SwooleTable.php index be046f30..3c154775 100644 --- a/src/Table/SwooleTable.php +++ b/src/Table/SwooleTable.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Table; - use Swoole\Table; class SwooleTable diff --git a/src/Task/Connectors/SwooleTaskConnector.php b/src/Task/Connectors/SwooleTaskConnector.php index 0ab71f3a..6e3c0664 100644 --- a/src/Task/Connectors/SwooleTaskConnector.php +++ b/src/Task/Connectors/SwooleTaskConnector.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Task\Connectors; - use Illuminate\Queue\Connectors\ConnectorInterface; use SwooleTW\Http\Helpers\FW; use SwooleTW\Http\Task\QueueFactory; diff --git a/src/Task/QueueFactory.php b/src/Task/QueueFactory.php index a9d8bb9a..72cdee8c 100644 --- a/src/Task/QueueFactory.php +++ b/src/Task/QueueFactory.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Task; - use Illuminate\Contracts\Queue\Queue; use Illuminate\Support\Arr; use SwooleTW\Http\Helpers\FW; @@ -31,7 +30,7 @@ class QueueFactory * * @const string */ - public const QUEUE_CLASS_PATH = __DIR__ . '/SwooleTaskQueue.php'; + public const QUEUE_CLASS_PATH = __DIR__.'/SwooleTaskQueue.php'; /** * @param \Swoole\Http\Server $server @@ -42,7 +41,7 @@ class QueueFactory public static function make($server, string $version): Queue { $isMatch = static::isFileVersionMatch($version); - $class = static::copy(static::stub($version), !$isMatch); + $class = static::copy(static::stub($version), ! $isMatch); return new $class($server); } @@ -55,8 +54,8 @@ public static function make($server, string $version): Queue public static function stub(string $version): string { return static::hasBreakingChanges($version) - ? __DIR__ . '/../../stubs/5.7/SwooleTaskQueue.stub' - : __DIR__ . '/../../stubs/5.6/SwooleTaskQueue.stub'; + ? __DIR__.'/../../stubs/5.7/SwooleTaskQueue.stub' + : __DIR__.'/../../stubs/5.6/SwooleTaskQueue.stub'; } /** @@ -67,7 +66,7 @@ public static function stub(string $version): string */ public static function copy(string $stub, bool $rewrite = false): string { - if (!file_exists(static::QUEUE_CLASS_PATH) || $rewrite) { + if (! file_exists(static::QUEUE_CLASS_PATH) || $rewrite) { copy($stub, static::QUEUE_CLASS_PATH); } diff --git a/src/Task/SwooleTaskJob.php b/src/Task/SwooleTaskJob.php index 701c2b55..526c8e03 100644 --- a/src/Task/SwooleTaskJob.php +++ b/src/Task/SwooleTaskJob.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Task; - use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Queue\Job as JobContract; use Illuminate\Queue\Jobs\Job; diff --git a/src/Task/SwooleTaskQueue.php b/src/Task/SwooleTaskQueue.php index 0a28fedf..760b9345 100644 --- a/src/Task/SwooleTaskQueue.php +++ b/src/Task/SwooleTaskQueue.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Task; - use Exception; use Illuminate\Contracts\Queue\Queue as QueueContract; use Illuminate\Queue\Queue; @@ -55,7 +54,7 @@ public function push($job, $data = '', $queue = null) */ public function pushRaw($payload, $queue = null, array $options = []) { - return $this->swoole->task($payload, !is_numeric($queue) ? 1 : (int)$queue); + return $this->swoole->task($payload, ! is_numeric($queue) ? 1 : (int)$queue); } /** diff --git a/src/Transformers/Request.php b/src/Transformers/Request.php index c5777f2a..2b48c6e1 100644 --- a/src/Transformers/Request.php +++ b/src/Transformers/Request.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Transformers; - use Illuminate\Http\Request as IlluminateRequest; use Swoole\Http\Request as SwooleRequest; use Symfony\Component\HttpFoundation\ParameterBag; @@ -29,7 +28,9 @@ class Request */ public static function make(SwooleRequest $swooleRequest) { - list($get, $post, $cookie, $files, $server, $content) + list( + $get, $post, $cookie, $files, $server, $content + ) = static::toIlluminateParameters($swooleRequest); return new static($get, $post, $cookie, $files, $server, $content); @@ -158,8 +159,8 @@ protected static function transformServerParameters(array $server, array $header $key = str_replace('-', '_', $key); $key = strtoupper($key); - if (!in_array($key, ['REMOTE_ADDR', 'SERVER_PORT', 'HTTPS'])) { - $key = 'HTTP_' . $key; + if (! in_array($key, ['REMOTE_ADDR', 'SERVER_PORT', 'HTTPS'])) { + $key = 'HTTP_'.$key; } $__SERVER[$key] = $value; @@ -185,8 +186,8 @@ public static function handleStatic($swooleRequest, $swooleResponse, string $pub return null; } - $filename = $publicPath . $uri; - if (!is_file($filename) || filesize($filename) === 0) { + $filename = $publicPath.$uri; + if (! is_file($filename) || filesize($filename) === 0) { return null; } @@ -194,8 +195,10 @@ public static function handleStatic($swooleRequest, $swooleResponse, string $pub $mime = mime_content_type($filename); if ($extension === 'js') { $mime = 'text/javascript'; - } else if ($extension === 'css') { - $mime = 'text/css'; + } else { + if ($extension === 'css') { + $mime = 'text/css'; + } } $swooleResponse->header('Content-Type', $mime); $swooleResponse->sendfile($filename); diff --git a/src/Transformers/Response.php b/src/Transformers/Response.php index 873e5508..a0af8eca 100644 --- a/src/Transformers/Response.php +++ b/src/Transformers/Response.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Transformers; - use Illuminate\Http\Response as IlluminateResponse; use Swoole\Http\Response as SwooleResponse; use Symfony\Component\HttpFoundation\BinaryFileResponse; @@ -67,7 +66,7 @@ protected function sendHeaders() $illuminateResponse = $this->getIlluminateResponse(); /* RFC2616 - 14.18 says all Responses need to have a Date */ - if (!$illuminateResponse->headers->has('Date')) { + if (! $illuminateResponse->headers->has('Date')) { $illuminateResponse->setDate(\DateTime::createFromFormat('U', time())); } @@ -90,9 +89,12 @@ protected function sendHeaders() foreach ($illuminateResponse->headers->getCookies() as $cookie) { // may need to consider rawcookie $this->swooleResponse->cookie( - $cookie->getName(), $cookie->getValue(), - $cookie->getExpiresTime(), $cookie->getPath(), - $cookie->getDomain(), $cookie->isSecure(), + $cookie->getName(), + $cookie->getValue(), + $cookie->getExpiresTime(), + $cookie->getPath(), + $cookie->getDomain(), + $cookie->isSecure(), $cookie->isHttpOnly() ); } @@ -108,10 +110,12 @@ protected function sendContent() if ($illuminateResponse instanceof StreamedResponse && property_exists($illuminateResponse, 'output')) { // TODO Add Streamed Response with output $this->swooleResponse->end($illuminateResponse->output); - } else if ($illuminateResponse instanceof BinaryFileResponse) { - $this->swooleResponse->sendfile($illuminateResponse->getFile()->getPathname()); } else { - $this->swooleResponse->end($illuminateResponse->getContent()); + if ($illuminateResponse instanceof BinaryFileResponse) { + $this->swooleResponse->sendfile($illuminateResponse->getFile()->getPathname()); + } else { + $this->swooleResponse->end($illuminateResponse->getContent()); + } } } @@ -142,7 +146,7 @@ public function getSwooleResponse() */ protected function setIlluminateResponse($illuminateResponse) { - if (!$illuminateResponse instanceof SymfonyResponse) { + if (! $illuminateResponse instanceof SymfonyResponse) { $content = (string)$illuminateResponse; $illuminateResponse = new IlluminateResponse($content); } diff --git a/src/Websocket/Authenticatable.php b/src/Websocket/Authenticatable.php index b33dfcac..8d07e7bf 100644 --- a/src/Websocket/Authenticatable.php +++ b/src/Websocket/Authenticatable.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Websocket; - use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use InvalidArgumentException; @@ -36,7 +35,7 @@ public function loginUsing(AuthenticatableContract $user) */ public function loginUsingId($userId) { - return $this->join(static::USER_PREFIX . $userId); + return $this->join(static::USER_PREFIX.$userId); } /** @@ -50,7 +49,7 @@ public function logout() return null; } - return $this->leave(static::USER_PREFIX . $userId); + return $this->leave(static::USER_PREFIX.$userId); } /** @@ -85,7 +84,7 @@ public function toUserId($userIds) $userIds = is_string($userIds) || is_integer($userIds) ? func_get_args() : $userIds; foreach ($userIds as $userId) { - $fds = $this->room->getClients(static::USER_PREFIX . $userId); + $fds = $this->room->getClients(static::USER_PREFIX.$userId); $this->to($fds); } @@ -97,7 +96,7 @@ public function toUserId($userIds) */ public function getUserId() { - if (!is_null($this->userId)) { + if (! is_null($this->userId)) { return $this->userId; } @@ -121,7 +120,7 @@ public function getUserId() */ public function isUserIdOnline($userId) { - return !empty($this->room->getClients(static::USER_PREFIX . $userId)); + return ! empty($this->room->getClients(static::USER_PREFIX.$userId)); } /** @@ -131,8 +130,8 @@ public function isUserIdOnline($userId) */ protected function checkUser($user) { - if (!$user instanceOf AuthenticatableContract) { - throw new InvalidArgumentException('user object must implement ' . AuthenticatableContract::class); + if (! $user instanceOf AuthenticatableContract) { + throw new InvalidArgumentException('user object must implement '.AuthenticatableContract::class); } } } diff --git a/src/Websocket/Facades/Room.php b/src/Websocket/Facades/Room.php index e702b9c8..72f3122a 100644 --- a/src/Websocket/Facades/Room.php +++ b/src/Websocket/Facades/Room.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Websocket\Facades; - use Illuminate\Support\Facades\Facade; /** diff --git a/src/Websocket/Facades/Websocket.php b/src/Websocket/Facades/Websocket.php index a7313000..5dcc4f05 100644 --- a/src/Websocket/Facades/Websocket.php +++ b/src/Websocket/Facades/Websocket.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Websocket\Facades; - use Illuminate\Support\Facades\Facade; /** diff --git a/src/Websocket/HandlerContract.php b/src/Websocket/HandlerContract.php index 658d5eea..c664026f 100644 --- a/src/Websocket/HandlerContract.php +++ b/src/Websocket/HandlerContract.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Websocket; - use Illuminate\Http\Request; use Swoole\Websocket\Frame; diff --git a/src/Websocket/Middleware/Authenticate.php b/src/Websocket/Middleware/Authenticate.php index 3ca343dd..ccc4bfa9 100644 --- a/src/Websocket/Middleware/Authenticate.php +++ b/src/Websocket/Middleware/Authenticate.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Websocket\Middleware; - use Closure; use Illuminate\Auth\AuthenticationException; use Illuminate\Contracts\Auth\Factory as Auth; diff --git a/src/Websocket/Middleware/DecryptCookies.php b/src/Websocket/Middleware/DecryptCookies.php index 6d564944..d199a703 100644 --- a/src/Websocket/Middleware/DecryptCookies.php +++ b/src/Websocket/Middleware/DecryptCookies.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Websocket\Middleware; - use Closure; use Illuminate\Contracts\Encryption\DecryptException; use Illuminate\Contracts\Encryption\Encrypter as EncrypterContract; diff --git a/src/Websocket/Middleware/StartSession.php b/src/Websocket/Middleware/StartSession.php index 44511480..332dfdb0 100644 --- a/src/Websocket/Middleware/StartSession.php +++ b/src/Websocket/Middleware/StartSession.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Websocket\Middleware; - use Closure; use Illuminate\Contracts\Session\Session; use Illuminate\Http\Request; @@ -88,6 +87,6 @@ public function getSession(Request $request) */ protected function sessionConfigured() { - return !is_null($this->manager->getSessionConfig()['driver'] ?? null); + return ! is_null($this->manager->getSessionConfig()['driver'] ?? null); } } diff --git a/src/Websocket/Parser.php b/src/Websocket/Parser.php index a9805048..d1722e22 100644 --- a/src/Websocket/Parser.php +++ b/src/Websocket/Parser.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Websocket; - use Illuminate\Support\Facades\App; abstract class Parser @@ -26,10 +25,13 @@ public function execute($server, $frame) $skip = false; foreach ($this->strategies as $strategy) { - $result = App::call($strategy . '@handle', [ - 'server' => $server, - 'frame' => $frame, - ]); + $result = App::call( + $strategy.'@handle', + [ + 'server' => $server, + 'frame' => $frame, + ] + ); if ($result === true) { $skip = true; break; diff --git a/src/Websocket/Push.php b/src/Websocket/Push.php index 40de4bd0..531a7e3e 100644 --- a/src/Websocket/Push.php +++ b/src/Websocket/Push.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Websocket; - use Illuminate\Support\Arr; /** @@ -64,8 +63,7 @@ private function __construct( bool $assigned, string $event, string $message = null - ) - { + ) { $this->opcode = $opcode; $this->sender = $sender; $this->descriptors = $descriptors; @@ -190,7 +188,7 @@ public function getMessage(): ?string */ public function isBroadcastToAllDescriptors(): bool { - return $this->isBroadcast() && !$this->isAssigned() && count($this->descriptors) > 0; + return $this->isBroadcast() && ! $this->isAssigned() && count($this->descriptors) > 0; } /** diff --git a/src/Websocket/Rooms/RedisRoom.php b/src/Websocket/Rooms/RedisRoom.php index 060ead65..16f28f35 100644 --- a/src/Websocket/Rooms/RedisRoom.php +++ b/src/Websocket/Rooms/RedisRoom.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Websocket\Rooms; - use Illuminate\Support\Arr; use Predis\Client as RedisClient; use Predis\Pipeline\Pipeline; @@ -58,7 +57,7 @@ public function prepare(RedisClient $redis = null): RoomContract */ public function setRedis(?RedisClient $redis = null) { - if (!$redis) { + if (! $redis) { $server = Arr::get($this->config, 'server', []); $options = Arr::get($this->config, 'options', []); @@ -203,7 +202,7 @@ public function getRooms(int $fd) */ protected function checkTable(string $table) { - if (!in_array($table, [RoomContract::ROOMS_KEY, RoomContract::DESCRIPTORS_KEY])) { + if (! in_array($table, [RoomContract::ROOMS_KEY, RoomContract::DESCRIPTORS_KEY])) { throw new \InvalidArgumentException('Invalid table name.'); } } diff --git a/src/Websocket/Rooms/RoomContract.php b/src/Websocket/Rooms/RoomContract.php index e3e91625..28aaefee 100644 --- a/src/Websocket/Rooms/RoomContract.php +++ b/src/Websocket/Rooms/RoomContract.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Websocket\Rooms; - interface RoomContract { /** diff --git a/src/Websocket/Rooms/TableRoom.php b/src/Websocket/Rooms/TableRoom.php index 42ddb74f..a02091e2 100644 --- a/src/Websocket/Rooms/TableRoom.php +++ b/src/Websocket/Rooms/TableRoom.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Websocket\Rooms; - use Swoole\Table; class TableRoom implements RoomContract @@ -88,7 +87,7 @@ public function delete(int $fd, $roomNames = []) foreach ($rooms as $room) { $fds = $this->getClients($room); - if (!in_array($fd, $fds)) { + if (! in_array($fd, $fds)) { continue; } @@ -178,9 +177,12 @@ public function setValue($key, array $value, string $table) { $this->checkTable($table); - $this->$table->set($key, [ - 'value' => json_encode($value), - ]); + $this->$table->set( + $key, + [ + 'value' => json_encode($value), + ] + ); return $this; } @@ -209,7 +211,7 @@ public function getValue(string $key, string $table) */ protected function checkTable(string $table) { - if (!property_exists($this, $table) || !$this->$table instanceof Table) { + if (! property_exists($this, $table) || ! $this->$table instanceof Table) { throw new \InvalidArgumentException('Invalid table name.'); } } diff --git a/src/Websocket/SimpleParser.php b/src/Websocket/SimpleParser.php index 1b0cadd0..fd3758ae 100644 --- a/src/Websocket/SimpleParser.php +++ b/src/Websocket/SimpleParser.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Websocket; - class SimpleParser extends Parser { /** @@ -20,10 +19,12 @@ class SimpleParser extends Parser */ public function encode(string $event, $data) { - return json_encode([ - 'event' => $event, - 'data' => $data, - ]); + return json_encode( + [ + 'event' => $event, + 'data' => $data, + ] + ); } /** diff --git a/src/Websocket/SocketIO/Packet.php b/src/Websocket/SocketIO/Packet.php index bb7b83e4..5da3f021 100644 --- a/src/Websocket/SocketIO/Packet.php +++ b/src/Websocket/SocketIO/Packet.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Websocket\SocketIO; - /** * Class Packet */ @@ -115,7 +114,7 @@ public static function getSocketType(string $packet) { $type = $packet[0] ?? null; - if (!array_key_exists($type, static::$socketTypes)) { + if (! array_key_exists($type, static::$socketTypes)) { return null; } diff --git a/src/Websocket/SocketIO/SocketIOParser.php b/src/Websocket/SocketIO/SocketIOParser.php index 8272ba4a..3c259bcf 100644 --- a/src/Websocket/SocketIO/SocketIOParser.php +++ b/src/Websocket/SocketIO/SocketIOParser.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Websocket\SocketIO; - use SwooleTW\Http\Websocket\Parser; use SwooleTW\Http\Websocket\SocketIO\Strategies\HeartbeatStrategy; @@ -28,12 +27,12 @@ class SocketIOParser extends Parser */ public function encode(string $event, $data) { - $packet = Packet::MESSAGE . Packet::EVENT; + $packet = Packet::MESSAGE.Packet::EVENT; $shouldEncode = is_array($data) || is_object($data); $data = $shouldEncode ? json_encode($data) : $data; $format = $shouldEncode ? '["%s",%s]' : '["%s","%s"]'; - return $packet . sprintf($format, $event, $data); + return $packet.sprintf($format, $event, $data); } /** diff --git a/src/Websocket/SocketIO/Strategies/HeartbeatStrategy.php b/src/Websocket/SocketIO/Strategies/HeartbeatStrategy.php index 88a8ae16..5d65bc09 100644 --- a/src/Websocket/SocketIO/Strategies/HeartbeatStrategy.php +++ b/src/Websocket/SocketIO/Strategies/HeartbeatStrategy.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Websocket\SocketIO\Strategies; - use SwooleTW\Http\Websocket\SocketIO\Packet; class HeartbeatStrategy diff --git a/src/Websocket/SocketIO/WebsocketHandler.php b/src/Websocket/SocketIO/WebsocketHandler.php index 34b0e34e..d76b60af 100644 --- a/src/Websocket/SocketIO/WebsocketHandler.php +++ b/src/Websocket/SocketIO/WebsocketHandler.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Websocket\SocketIO; - use Illuminate\Http\Request; use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\Config; @@ -21,15 +20,17 @@ class WebsocketHandler implements HandlerContract */ public function onOpen($fd, Request $request) { - if (!$request->input('sid')) { - $payload = json_encode([ - 'sid' => base64_encode(uniqid()), - 'upgrades' => [], - 'pingInterval' => Config::get('swoole_websocket.ping_interval'), - 'pingTimeout' => Config::get('swoole_websocket.ping_timeout'), - ]); - $initPayload = Packet::OPEN . $payload; - $connectPayload = Packet::MESSAGE . Packet::CONNECT; + if (! $request->input('sid')) { + $payload = json_encode( + [ + 'sid' => base64_encode(uniqid()), + 'upgrades' => [], + 'pingInterval' => Config::get('swoole_websocket.ping_interval'), + 'pingTimeout' => Config::get('swoole_websocket.ping_timeout'), + ] + ); + $initPayload = Packet::OPEN.$payload; + $connectPayload = Packet::MESSAGE.Packet::CONNECT; App::make('swoole.server')->push($fd, $initPayload); App::make('swoole.server')->push($fd, $connectPayload); diff --git a/src/Websocket/Websocket.php b/src/Websocket/Websocket.php index caad0773..b945d02b 100644 --- a/src/Websocket/Websocket.php +++ b/src/Websocket/Websocket.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Websocket; - use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Pipeline\Pipeline as PipelineContract; use Illuminate\Support\Facades\App; @@ -102,7 +101,7 @@ public function to($values): self $values = is_string($values) || is_integer($values) ? func_get_args() : $values; foreach ($values as $value) { - if (!in_array($value, $this->to)) { + if (! in_array($value, $this->to)) { $this->to[] = $value; } } @@ -153,7 +152,7 @@ public function leave($rooms = []): self public function emit(string $event, $data): bool { $fds = $this->getFds(); - $assigned = !empty($this->to); + $assigned = ! empty($this->to); // if no fds are found, but rooms are assigned // that means trying to emit to a non-existing room @@ -162,17 +161,19 @@ public function emit(string $event, $data): bool return false; } - $result = App::make('swoole.server')->task([ - 'action' => static::PUSH_ACTION, - 'data' => [ - 'sender' => $this->sender, - 'fds' => $fds, - 'broadcast' => $this->isBroadcast, - 'assigned' => $assigned, - 'event' => $event, - 'message' => $data, - ], - ]); + $result = App::make('swoole.server')->task( + [ + 'action' => static::PUSH_ACTION, + 'data' => [ + 'sender' => $this->sender, + 'fds' => $fds, + 'broadcast' => $this->isBroadcast, + 'assigned' => $assigned, + 'event' => $event, + 'message' => $data, + ], + ] + ); $this->reset(); @@ -203,7 +204,7 @@ public function in($room) */ public function on(string $event, $callback) { - if (!is_string($callback) && !is_callable($callback)) { + if (! is_string($callback) && ! is_callable($callback)) { throw new InvalidArgumentException( 'Invalid websocket callback. Must be a string or callable.' ); @@ -236,7 +237,7 @@ public function eventExists(string $event) */ public function call(string $event, $data = null) { - if (!$this->eventExists($event)) { + if (! $this->eventExists($event)) { return null; } @@ -249,10 +250,13 @@ public function call(string $event, $data = null) $data = $this->setRequestThroughMiddleware($data); } - return App::call($this->callbacks[$event], [ - 'websocket' => $this, - $dataKey => $data, - ]); + return App::call( + $this->callbacks[$event], + [ + 'websocket' => $this, + $dataKey => $data, + ] + ); } /** From 0b89e1d6812d0d37ccd829be74394a13c47e4156 Mon Sep 17 00:00:00 2001 From: Fractal Zombie Date: Sun, 23 Dec 2018 00:59:45 +0200 Subject: [PATCH 019/161] More code refactoring. --- .travis.yml | 2 +- composer.json | 11 ++- src/Commands/HttpServerCommand.php | 7 +- src/Concerns/InteractsWithWebsocket.php | 34 ++++---- src/Concerns/ResetApplication.php | 2 +- src/Concerns/WithApplication.php | 4 +- src/Controllers/SocketIOController.php | 2 +- src/Coroutine/Connectors/ConnectorFactory.php | 8 +- src/Coroutine/PDO.php | 2 +- src/Coroutine/PDOStatement.php | 12 +-- src/Helpers/Alias.php | 17 ++++ src/Helpers/Service.php | 16 ---- src/HttpServiceProvider.php | 63 +++++++-------- src/LaravelServiceProvider.php | 7 +- src/LumenServiceProvider.php | 9 ++- src/Server/Facades/Sandbox.php | 3 +- src/Server/Facades/Server.php | 8 +- src/Server/Manager.php | 29 +++---- src/Server/Sandbox.php | 53 ++++++++++--- src/Task/QueueFactory.php | 6 +- src/Task/SwooleTaskQueue.php | 2 +- src/Transformers/Request.php | 78 +++++++++---------- src/Transformers/Response.php | 2 +- src/Transformers/StreamedResponse.php | 38 +++++++++ src/Websocket/Authenticatable.php | 10 +-- src/Websocket/Facades/Room.php | 3 +- src/Websocket/Middleware/DecryptCookies.php | 2 +- src/Websocket/Parser.php | 2 +- src/Websocket/Push.php | 5 +- src/Websocket/Rooms/TableRoom.php | 2 +- src/Websocket/SocketIO/Packet.php | 2 +- src/Websocket/SocketIO/SocketIOParser.php | 4 +- src/Websocket/SocketIO/WebsocketHandler.php | 9 ++- src/Websocket/Websocket.php | 54 +++++++------ tests/Server/ManagerTest.php | 38 ++++++--- tests/SocketIO/WebsocketHandlerTest.php | 3 +- tests/Transformers/RequestTest.php | 4 +- tests/Websocket/WebsocketTest.php | 5 +- 38 files changed, 329 insertions(+), 229 deletions(-) create mode 100644 src/Helpers/Alias.php delete mode 100644 src/Helpers/Service.php create mode 100644 src/Transformers/StreamedResponse.php diff --git a/.travis.yml b/.travis.yml index 8b7faf44..15df5365 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,4 +37,4 @@ script: - vendor/bin/phpunit --coverage-clover build/logs/clover.xml after_success: - - vendor/bin/coveralls -v + - vendor/bin/php-coveralls -v diff --git a/composer.json b/composer.json index b45c7ab5..6dd18845 100644 --- a/composer.json +++ b/composer.json @@ -26,13 +26,16 @@ "illuminate/contracts": "~5.3", "illuminate/http": "~5.3", "illuminate/support": "~5.3", - "predis/predis": "^1.1" + "predis/predis": "^1.1", + "ext-json": "*", + "ext-fileinfo": "*", + "ext-pdo": "*" }, "require-dev": { "laravel/lumen-framework": "~5.3", - "phpunit/phpunit": "^6.1", - "phpunit/php-code-coverage": "^5.2", - "satooshi/php-coveralls": "^1.0", + "phpunit/phpunit": "^7.5", + "phpunit/php-code-coverage": "^6.1", + "php-coveralls/php-coveralls": "^2.1", "mockery/mockery": "~1.0", "codedungeon/phpunit-result-printer": "^0.14.0", "php-mock/php-mock": "^2.0" diff --git a/src/Commands/HttpServerCommand.php b/src/Commands/HttpServerCommand.php index 1bbe7582..33ebe8eb 100644 --- a/src/Commands/HttpServerCommand.php +++ b/src/Commands/HttpServerCommand.php @@ -5,6 +5,7 @@ use Illuminate\Console\Command; use Illuminate\Support\Arr; use Swoole\Process; +use SwooleTW\Http\Server\Manager; use Throwable; /** @@ -95,12 +96,12 @@ protected function start() $this->info("Swoole http server started: "); if ($this->isDaemon()) { $this->info( - '> (You can run this command to ensure the '. + '> (You can run this command to ensure the ' . 'swoole_http_server process is running: ps aux|grep "swoole")' ); } - $this->laravel->make('swoole.manager')->run(); + $this->laravel->make(Manager::class)->run(); } /** @@ -292,7 +293,7 @@ protected function getCurrentPid() $path = $this->getPidPath(); return $this->currentPid = file_exists($path) - ? (int)file_get_contents($path) ?? $this->removePidFile() + ? (int) file_get_contents($path) ?? $this->removePidFile() : null; } diff --git a/src/Concerns/InteractsWithWebsocket.php b/src/Concerns/InteractsWithWebsocket.php index 81aa724c..3521bc53 100644 --- a/src/Concerns/InteractsWithWebsocket.php +++ b/src/Concerns/InteractsWithWebsocket.php @@ -6,7 +6,9 @@ use Illuminate\Pipeline\Pipeline; use Illuminate\Support\Arr; use SwooleTW\Http\Exceptions\WebsocketNotSetInConfigException; -use SwooleTW\Http\Helpers\Service; +use SwooleTW\Http\Helpers\Alias; +use SwooleTW\Http\Server\Facades\Server; +use SwooleTW\Http\Server\Sandbox; use SwooleTW\Http\Transformers\Request; use SwooleTW\Http\Websocket\HandlerContract; use SwooleTW\Http\Websocket\Parser; @@ -54,8 +56,8 @@ trait InteractsWithWebsocket public function onOpen($swooleRequest) { $illuminateRequest = Request::make($swooleRequest)->toIlluminate(); - $websocket = $this->app->make(Service::WEBSOCKET_ALIAS); - $sandbox = $this->app->make(Service::SANDBOX_ALIAS); + $websocket = $this->app->make(Websocket::class); + $sandbox = $this->app->make(Sandbox::class); try { $websocket->reset(true)->setSender($swooleRequest->fd); @@ -94,8 +96,8 @@ public function onMessage($server, $frame) return; } - $websocket = $this->app->make(Service::WEBSOCKET_ALIAS); - $sandbox = $this->app->make(Service::SANDBOX_ALIAS); + $websocket = $this->app->make(Websocket::class); + $sandbox = $this->app->make(Sandbox::class); try { // decode raw message via parser @@ -132,7 +134,7 @@ public function onClose($server, $fd, $reactorId) return; } - $websocket = $this->app->make(Service::WEBSOCKET_ALIAS); + $websocket = $this->app->make(Websocket::class); try { $websocket->reset(true)->setSender($fd); @@ -172,7 +174,7 @@ public function pushMessage($server, array $data) // push message to designated fds foreach ($push->getDescriptors() as $descriptor) { - if ($server->exist($descriptor) || ! $push->isBroadcastToDescriptor((int)$descriptor)) { + if ($server->exist($descriptor) || ! $push->isBroadcastToDescriptor((int) $descriptor)) { $server->push($descriptor, $payload, $push->getOpcode()); } } @@ -205,7 +207,7 @@ public function getPayloadParser() */ protected function prepareWebsocket() { - $config = $this->container->make(Service::CONFIG_ALIAS); + $config = $this->container->make(Alias::CONFIG); $isWebsocket = $config->get('swoole_http.websocket.enabled'); $parser = $config->get('swoole_websocket.parser'); @@ -225,7 +227,7 @@ protected function prepareWebsocket() */ protected function isServerWebsocket(int $fd): bool { - $info = $this->container->make(Service::SERVER_ALIAS)->connection_info($fd); + $info = $this->container->make(Server::class)->connection_info($fd); return Arr::has($info, 'websocket_status') && Arr::get($info, 'websocket_status'); } @@ -253,7 +255,7 @@ protected function filterWebsocket(array $descriptors): array */ protected function prepareWebsocketHandler() { - $handlerClass = $this->container->make(Service::CONFIG_ALIAS)->get('swoole_websocket.handler'); + $handlerClass = $this->container->make(Alias::CONFIG)->get('swoole_websocket.handler'); if (! $handlerClass) { throw new WebsocketNotSetInConfigException; @@ -303,7 +305,7 @@ protected function createRoom(string $class, array $settings): RoomContract protected function bindRoom(): void { $this->app->singleton(RoomContract::class, function (Container $container) { - $config = $container->make(Service::CONFIG_ALIAS); + $config = $container->make(Alias::CONFIG); $driver = $config->get('swoole_websocket.default'); $settings = $config->get("swoole_websocket.settings.{$driver}"); $className = $config->get("swoole_websocket.drivers.{$driver}"); @@ -311,7 +313,7 @@ protected function bindRoom(): void return $this->createRoom($className, $settings); }); - $this->app->alias(RoomContract::class, 'swoole.room'); + $this->app->alias(RoomContract::class, Alias::ROOM); } /** @@ -320,10 +322,10 @@ protected function bindRoom(): void protected function bindWebsocket() { $this->app->singleton(Websocket::class, function (Container $app) { - return new Websocket($app->make(Service::ROOM_ALIAS), new Pipeline($app)); + return new Websocket($app->make(RoomContract::class), new Pipeline($app)); }); - $this->app->alias(Websocket::class, Service::WEBSOCKET_ALIAS); + $this->app->alias(Websocket::class, 'swoole.websocket'); } /** @@ -331,10 +333,10 @@ protected function bindWebsocket() */ protected function loadWebsocketRoutes() { - $routePath = $this->container->make(Service::CONFIG_ALIAS)->get('swoole_websocket.route_file'); + $routePath = $this->container->make(Alias::CONFIG)->get('swoole_websocket.route_file'); if (! file_exists($routePath)) { - $routePath = __DIR__.'/../../routes/websocket.php'; + $routePath = __DIR__ . '/../../routes/websocket.php'; } return require $routePath; diff --git a/src/Concerns/ResetApplication.php b/src/Concerns/ResetApplication.php index a6c96c01..3fcb9af2 100644 --- a/src/Concerns/ResetApplication.php +++ b/src/Concerns/ResetApplication.php @@ -74,7 +74,7 @@ protected function setInitialResetters() foreach ($resetters as $resetter) { $resetterClass = $app->make($resetter); if (! $resetterClass instanceof ResetterContract) { - throw new SandboxException("{$resetter} must implement ".ResetterContract::class); + throw new SandboxException("{$resetter} must implement " . ResetterContract::class); } $this->resetters[$resetter] = $resetterClass; } diff --git a/src/Concerns/WithApplication.php b/src/Concerns/WithApplication.php index 8aa54ec4..3c56512d 100644 --- a/src/Concerns/WithApplication.php +++ b/src/Concerns/WithApplication.php @@ -6,7 +6,7 @@ use Illuminate\Contracts\Http\Kernel; use Illuminate\Support\Facades\Facade; use SwooleTW\Http\Exceptions\FrameworkNotSupportException; -use SwooleTW\Http\Helpers\Service; +use SwooleTW\Http\Helpers\Alias; /** * Trait WithApplication @@ -149,7 +149,7 @@ public function getBasePath() */ protected function preResolveInstances() { - $resolves = $this->container->make(Service::CONFIG_ALIAS)->get('swoole_http.pre_resolved', []); + $resolves = $this->container->make(Alias::CONFIG)->get('swoole_http.pre_resolved', []); foreach ($resolves as $abstract) { if ($this->getApplication()->offsetExists($abstract)) { diff --git a/src/Controllers/SocketIOController.php b/src/Controllers/SocketIOController.php index 321aed94..159adfd8 100644 --- a/src/Controllers/SocketIOController.php +++ b/src/Controllers/SocketIOController.php @@ -34,7 +34,7 @@ public function upgrade(Request $request) ] ); - return '97:0'.$payload.'2:40'; + return '97:0' . $payload . '2:40'; } public function reject() diff --git a/src/Coroutine/Connectors/ConnectorFactory.php b/src/Coroutine/Connectors/ConnectorFactory.php index 32f6e437..fd402338 100644 --- a/src/Coroutine/Connectors/ConnectorFactory.php +++ b/src/Coroutine/Connectors/ConnectorFactory.php @@ -29,7 +29,7 @@ class ConnectorFactory * * @const string */ - public const CONNECTOR_CLASS_PATH = __DIR__.'/MySqlConnector.php'; + public const CONNECTOR_CLASS_PATH = __DIR__ . '/MySqlConnector.php'; /** * @param string $version @@ -41,7 +41,7 @@ public static function make(string $version): MySqlConnector $isMatch = static::isFileVersionMatch($version); $class = static::copy(static::stub($version), ! $isMatch); - return new $class(); + return new $class; } /** @@ -52,8 +52,8 @@ public static function make(string $version): MySqlConnector public static function stub(string $version): string { return static::hasBreakingChanges($version) - ? __DIR__.'/../../../stubs/5.6/MySqlConnector.stub' - : __DIR__.'/../../../stubs/5.5/MySqlConnector.stub'; + ? __DIR__ . '/../../../stubs/5.6/MySqlConnector.stub' + : __DIR__ . '/../../../stubs/5.5/MySqlConnector.stub'; } /** diff --git a/src/Coroutine/PDO.php b/src/Coroutine/PDO.php index 54e44972..bf51a519 100644 --- a/src/Coroutine/PDO.php +++ b/src/Coroutine/PDO.php @@ -61,7 +61,7 @@ public function __construct(string $dsn, string $username = '', string $password */ protected function setClient($client = null) { - $this->client = $client ?: new \Swoole\Coroutine\Mysql(); + $this->client = $client ?: new \Swoole\Coroutine\Mysql; } /** diff --git a/src/Coroutine/PDOStatement.php b/src/Coroutine/PDOStatement.php index 62a32d48..2ebae9b8 100644 --- a/src/Coroutine/PDOStatement.php +++ b/src/Coroutine/PDOStatement.php @@ -74,7 +74,7 @@ public function bindValue($parameter, $variable, $type = null) if (! method_exists($variable, '__toString')) { return false; } else { - $variable = (string)$variable; + $variable = (string) $variable; } } @@ -154,7 +154,8 @@ private function transStyle( $fetchStyle = null, $fetchArgument = null, $ctorArgs = null - ) { + ) + { if (! is_array($rawData)) { return false; } @@ -178,7 +179,7 @@ private function transStyle( break; case PDO::FETCH_OBJ: foreach ($rawData as $row) { - $resultSet[] = (object)$row; + $resultSet[] = (object) $row; } break; case PDO::FETCH_NUM: @@ -199,11 +200,12 @@ public function fetch( $cursorOrientation = null, $cursorOffset = null, $fetchArgument = null - ) { + ) + { $this->__executeWhenStringQueryEmpty(); $cursorOrientation = is_null($cursorOrientation) ? PDO::FETCH_ORI_NEXT : $cursorOrientation; - $cursorOffset = is_null($cursorOffset) ? 0 : (int)$cursorOffset; + $cursorOffset = is_null($cursorOffset) ? 0 : (int) $cursorOffset; switch ($cursorOrientation) { case PDO::FETCH_ORI_ABS: diff --git a/src/Helpers/Alias.php b/src/Helpers/Alias.php new file mode 100644 index 00000000..96e53256 --- /dev/null +++ b/src/Helpers/Alias.php @@ -0,0 +1,17 @@ +publishes( - [ - __DIR__.'/../config/swoole_http.php' => base_path('config/swoole_http.php'), - __DIR__.'/../config/swoole_websocket.php' => base_path('config/swoole_websocket.php'), - __DIR__.'/../routes/websocket.php' => base_path('routes/websocket.php'), - ], - 'laravel-swoole' - ); - - if ($this->app->make(Service::CONFIG_ALIAS)->get('swoole_http.websocket.enabled')) { + $this->publishes([ + __DIR__ . '/../config/swoole_http.php' => base_path('config/swoole_http.php'), + __DIR__ . '/../config/swoole_websocket.php' => base_path('config/swoole_websocket.php'), + __DIR__ . '/../routes/websocket.php' => base_path('routes/websocket.php'), + ], 'laravel-swoole'); + + if ($this->app->make(Alias::CONFIG)->get('swoole_http.websocket.enabled')) { $this->bootRoutes(); } } @@ -92,8 +91,8 @@ public function boot() */ protected function mergeConfigs() { - $this->mergeConfigFrom(__DIR__.'/../config/swoole_http.php', 'swoole_http'); - $this->mergeConfigFrom(__DIR__.'/../config/swoole_websocket.php', 'swoole_websocket'); + $this->mergeConfigFrom(__DIR__ . '/../config/swoole_http.php', 'swoole_http'); + $this->mergeConfigFrom(__DIR__ . '/../config/swoole_websocket.php', 'swoole_websocket'); } /** @@ -101,7 +100,7 @@ protected function mergeConfigs() */ protected function setIsWebsocket() { - $this->isWebsocket = $this->app->make(Service::CONFIG_ALIAS)->get('swoole_http.websocket.enabled'); + $this->isWebsocket = $this->app->make(Alias::CONFIG)->get('swoole_http.websocket.enabled'); } /** @@ -109,11 +108,9 @@ protected function setIsWebsocket() */ protected function registerCommands() { - $this->commands( - [ - HttpServerCommand::class, - ] - ); + $this->commands([ + HttpServerCommand::class, + ]); } /** @@ -122,7 +119,7 @@ protected function registerCommands() protected function createSwooleServer() { $server = $this->isWebsocket ? WebsocketServer::class : HttpServer::class; - $config = $this->app->make(Service::CONFIG_ALIAS); + $config = $this->app->make(Alias::CONFIG); $host = $config->get('swoole_http.server.host'); $port = $config->get('swoole_http.server.port'); $socketType = $config->get('swoole_http.server.socket_type', SWOOLE_SOCK_TCP); @@ -136,7 +133,7 @@ protected function createSwooleServer() */ protected function configureSwooleServer() { - $config = $this->app->make(Service::CONFIG_ALIAS); + $config = $this->app->make(Alias::CONFIG); $options = $config->get('swoole_http.server.options'); // only enable task worker in websocket mode and for queue driver @@ -162,8 +159,7 @@ protected function registerServer() return static::$server; }); - - $this->app->alias(Server::class, Service::SERVER_ALIAS); + $this->app->alias(Server::class, Alias::SERVER); } /** @@ -171,18 +167,18 @@ protected function registerServer() */ protected function registerDatabaseDriver() { - $this->app->extend('db', function ($db) { + $this->app->extend(DatabaseManager::class, function (DatabaseManager $db) { $db->extend('mysql-coroutine', function ($config, $name) { $config = $this->getMergedDatabaseConfig($config, $name); $connection = new MySqlConnection( $this->getNewMySqlConnection($config), - $config['database'], - $config['prefix'], + Arr::get($config, 'database'), + Arr::get($config, 'prefix'), $config ); - if (isset($config['read'])) { + if (Arr::has($config, 'read')) { $connection->setReadPdo($this->getNewMySqlConnection($config)); } @@ -203,14 +199,9 @@ protected function registerDatabaseDriver() */ protected function getMergedDatabaseConfig(array $config, string $name) { - $config['name'] = $name; - - if (isset($config['read'])) { - $config = array_merge($config, $config['read']); - } - if (isset($config['write'])) { - $config = array_merge($config, $config['write']); - } + $config = Arr::add($config, 'name', $name); + $config = array_merge($config, Arr::get($config, 'read', [])); + $config = array_merge($config, Arr::get($config, 'write', [])); return $config; } @@ -232,7 +223,7 @@ protected function getNewMySqlConnection(array $config) */ protected function registerSwooleQueueDriver() { - $this->app->afterResolving('queue', function (Manager $manager) { + $this->app->afterResolving(Alias::QUEUE, function (Manager $manager) { $manager->addConnector('swoole', function () { return new SwooleTaskConnector($this->app->make(Server::class)); }); diff --git a/src/LaravelServiceProvider.php b/src/LaravelServiceProvider.php index 5cf86a30..711ead56 100644 --- a/src/LaravelServiceProvider.php +++ b/src/LaravelServiceProvider.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http; +use SwooleTW\Http\Helpers\Alias; use SwooleTW\Http\Server\Manager; /** @@ -16,9 +17,11 @@ class LaravelServiceProvider extends HttpServiceProvider */ protected function registerManager() { - $this->app->singleton('swoole.manager', function ($app) { + $this->app->singleton(Manager::class, function ($app) { return new Manager($app, 'laravel'); }); + + $this->app->alias(Manager::class, Alias::MANAGER); } /** @@ -28,6 +31,6 @@ protected function registerManager() */ protected function bootRoutes() { - require __DIR__.'/../routes/laravel_routes.php'; + require __DIR__ . '/../routes/laravel_routes.php'; } } diff --git a/src/LumenServiceProvider.php b/src/LumenServiceProvider.php index 40f218b4..499af4bc 100644 --- a/src/LumenServiceProvider.php +++ b/src/LumenServiceProvider.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http; +use SwooleTW\Http\Helpers\Alias; use SwooleTW\Http\Server\Manager; /** @@ -16,9 +17,11 @@ class LumenServiceProvider extends HttpServiceProvider */ protected function registerManager() { - $this->app->singleton('swoole.manager', function ($app) { + $this->app->singleton(Manager::class, function ($app) { return new Manager($app, 'lumen'); }); + + $this->app->alias(Manager::class, Alias::MANAGER); } /** @@ -32,11 +35,11 @@ protected function bootRoutes() if (property_exists($app, 'router')) { $app->router->group(['namespace' => 'SwooleTW\Http\Controllers'], function ($app) { - require __DIR__.'/../routes/lumen_routes.php'; + require __DIR__ . '/../routes/lumen_routes.php'; }); } else { $app->group(['namespace' => 'App\Http\Controllers'], function ($app) { - require __DIR__.'/../routes/lumen_routes.php'; + require __DIR__ . '/../routes/lumen_routes.php'; }); } } diff --git a/src/Server/Facades/Sandbox.php b/src/Server/Facades/Sandbox.php index 8c468254..8cee44dd 100644 --- a/src/Server/Facades/Sandbox.php +++ b/src/Server/Facades/Sandbox.php @@ -3,6 +3,7 @@ namespace SwooleTW\Http\Server\Facades; use Illuminate\Support\Facades\Facade; +use SwooleTW\Http\Helpers\Alias; class Sandbox extends Facade { @@ -13,6 +14,6 @@ class Sandbox extends Facade */ protected static function getFacadeAccessor() { - return 'swoole.sandbox'; + return Alias::SANDBOX; } } \ No newline at end of file diff --git a/src/Server/Facades/Server.php b/src/Server/Facades/Server.php index 7a34102a..4dd8195a 100644 --- a/src/Server/Facades/Server.php +++ b/src/Server/Facades/Server.php @@ -3,7 +3,13 @@ namespace SwooleTW\Http\Server\Facades; use Illuminate\Support\Facades\Facade; +use SwooleTW\Http\Helpers\Alias; +/** + * Class Server + * + * @mixin \Swoole\Http\Server + */ class Server extends Facade { /** @@ -13,6 +19,6 @@ class Server extends Facade */ protected static function getFacadeAccessor() { - return 'swoole.server'; + return Alias::SERVER; } } \ No newline at end of file diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 3eb47bb1..72ecde05 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -5,12 +5,14 @@ use Exception; use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Debug\ExceptionHandler; +use Illuminate\Events\Dispatcher; use Illuminate\Support\Facades\Facade; use Illuminate\Support\Str; use SwooleTW\Http\Concerns\InteractsWithSwooleTable; use SwooleTW\Http\Concerns\InteractsWithWebsocket; use SwooleTW\Http\Concerns\WithApplication; use SwooleTW\Http\Helpers\OS; +use SwooleTW\Http\Server\Facades\Server; use SwooleTW\Http\Task\SwooleTaskJob; use SwooleTW\Http\Transformers\Request; use SwooleTW\Http\Transformers\Response; @@ -88,7 +90,7 @@ public function __construct(Container $container, $framework, $basePath = null) */ public function run() { - $this->container->make('swoole.server')->start(); + $this->container->make(Server::class)->start(); } /** @@ -96,7 +98,7 @@ public function run() */ public function stop() { - $this->container->make('swoole.server')->shutdown(); + $this->container->make(Server::class)->shutdown(); } /** @@ -120,7 +122,7 @@ protected function setSwooleServerListeners() $this->container->make('events')->fire("swoole.$event", func_get_args()); }; - $this->container->make('swoole.server')->on($event, $callback); + $this->container->make(Server::class)->on($event, $callback); } } @@ -143,7 +145,7 @@ public function onStart() public function onManagerStart() { $this->setProcessName('manager process'); - $this->container->make('events')->fire('swoole.managerStart', func_get_args()); + $this->container->make(Dispatcher::class)->fire('swoole.managerStart', func_get_args()); } /** @@ -194,6 +196,7 @@ public function onRequest($swooleRequest, $swooleResponse) $this->app->make('events')->fire('swoole.request'); $this->resetOnRequest(); + $sandbox = $this->app->make(Sandbox::class);; $handleStatic = $this->container->make('config')->get('swoole_http.handle_static_files', true); $publicPath = $this->container->make('config')->get('swoole_http.server.public_path', base_path('public')); @@ -206,25 +209,23 @@ public function onRequest($swooleRequest, $swooleResponse) $illuminateRequest = Request::make($swooleRequest)->toIlluminate(); // set current request to sandbox - $this->app->make('swoole.sandbox')->setRequest($illuminateRequest); + $sandbox->setRequest($illuminateRequest); // enable sandbox - $this->app->make('swoole.sandbox')->enable(); + $sandbox->enable(); // handle request via laravel/lumen's dispatcher - $illuminateResponse = $this->app->make('swoole.sandbox')->run($illuminateRequest); - $response = Response::make($illuminateResponse, $swooleResponse); - $response->send(); + $illuminateResponse = $sandbox->run($illuminateRequest); + Response::make($illuminateResponse, $swooleResponse)->send(); } catch (Throwable $e) { try { $exceptionResponse = $this->app->make(ExceptionHandler::class)->render(null, $e); - $response = Response::make($exceptionResponse, $swooleResponse); - $response->send(); + Response::make($exceptionResponse, $swooleResponse)->send(); } catch (Throwable $e) { $this->logServerError($e); } } finally { // disable and recycle sandbox resource - $this->app->make('swoole.sandbox')->disable(); + $sandbox->disable(); } } @@ -235,7 +236,7 @@ protected function resetOnRequest() { // Reset websocket data if ($this->isServerWebsocket) { - $this->app->make('swoole.websocket')->reset(true); + $this->app->make(Websocket::class)->reset(true); } } @@ -339,7 +340,7 @@ protected function getPidFile() protected function createPidFile() { $pidFile = $this->getPidFile(); - $pid = $this->container['swoole.server']->master_pid; + $pid = $this->container->make(Server::class)->master_pid; file_put_contents($pidFile, $pid); } diff --git a/src/Server/Sandbox.php b/src/Server/Sandbox.php index ccf0f74c..29c50bb1 100644 --- a/src/Server/Sandbox.php +++ b/src/Server/Sandbox.php @@ -31,6 +31,11 @@ class Sandbox /** * Constructor + * + * @param null $app + * @param null $framework + * + * @throws \SwooleTW\Http\Exceptions\SandboxException */ public function __construct($app = null, $framework = null) { @@ -45,6 +50,10 @@ public function __construct($app = null, $framework = null) /** * Set framework type. + * + * @param string $framework + * + * @return \SwooleTW\Http\Server\Sandbox */ public function setFramework(string $framework) { @@ -65,6 +74,8 @@ public function getFramework() * Set a base application. * * @param \Illuminate\Container\Container + * + * @return \SwooleTW\Http\Server\Sandbox */ public function setBaseApp(Container $app) { @@ -77,6 +88,8 @@ public function setBaseApp(Container $app) * Set current request. * * @param \Illuminate\Http\Request + * + * @return \SwooleTW\Http\Server\Sandbox */ public function setRequest(Request $request) { @@ -89,6 +102,8 @@ public function setRequest(Request $request) * Set current snapshot. * * @param \Illuminate\Container\Container + * + * @return \SwooleTW\Http\Server\Sandbox */ public function setSnapshot(Container $snapshot) { @@ -99,6 +114,8 @@ public function setSnapshot(Container $snapshot) /** * Initialize based on base app. + * + * @throws \SwooleTW\Http\Exceptions\SandboxException */ public function initialize() { @@ -147,6 +164,8 @@ public function getApplication() * @param \Illuminate\Http\Request $request * * @return \Illuminate\Http\Response + * @throws \SwooleTW\Http\Exceptions\SandboxException + * @throws \ReflectionException */ public function run(Request $request) { @@ -169,6 +188,7 @@ public function run(Request $request) * @param \Illuminate\Http\Request $request * * @return \Illuminate\Http\Response + * @throws \ReflectionException */ protected function prepareResponse(Request $request) { @@ -187,6 +207,7 @@ protected function prepareResponse(Request $request) * @param \Illuminate\Http\Request $request * * @return \Illuminate\Http\Response + * @throws \ReflectionException */ protected function prepareObResponse(Request $request) { @@ -203,7 +224,7 @@ protected function prepareObResponse(Request $request) } elseif ($response instanceof SymfonyResponse) { $content = $response->getContent(); } elseif (! $isFile = $response instanceof BinaryFileResponse) { - $content = (string)$response; + $content = (string) $response; } // process terminating logics @@ -214,7 +235,7 @@ protected function prepareObResponse(Request $request) if ($isStream) { $response->output = ob_get_contents(); } else { - $response->setContent(ob_get_contents().$content); + $response->setContent(ob_get_contents() . $content); } } @@ -258,29 +279,35 @@ public function isLaravel() /** * @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Response $response + * + * @throws \ReflectionException */ public function terminate(Request $request, $response) { if ($this->isLaravel()) { $this->getKernel()->terminate($request, $response); - } else { - $app = $this->getApplication(); - $reflection = new \ReflectionObject($app); - $middleware = $reflection->getProperty('middleware'); - $middleware->setAccessible(true); + return; + } - $callTerminableMiddleware = $reflection->getMethod('callTerminableMiddleware'); - $callTerminableMiddleware->setAccessible(true); + $app = $this->getApplication(); + $reflection = new \ReflectionObject($app); - if (count($middleware->getValue($app)) > 0) { - $callTerminableMiddleware->invoke($app, $response); - } + $middleware = $reflection->getProperty('middleware'); + $middleware->setAccessible(true); + + $callTerminableMiddleware = $reflection->getMethod('callTerminableMiddleware'); + $callTerminableMiddleware->setAccessible(true); + + if (count($middleware->getValue($app)) > 0) { + $callTerminableMiddleware->invoke($app, $response); } } /** * Set laravel snapshot to container and facade. + * + * @throws \SwooleTW\Http\Exceptions\SandboxException */ public function enable() { @@ -303,6 +330,8 @@ public function disable() /** * Replace app's self bindings. + * + * @param \Illuminate\Container\Container $app */ public function setInstance(Container $app) { diff --git a/src/Task/QueueFactory.php b/src/Task/QueueFactory.php index 72cdee8c..4610827c 100644 --- a/src/Task/QueueFactory.php +++ b/src/Task/QueueFactory.php @@ -30,7 +30,7 @@ class QueueFactory * * @const string */ - public const QUEUE_CLASS_PATH = __DIR__.'/SwooleTaskQueue.php'; + public const QUEUE_CLASS_PATH = __DIR__ . '/SwooleTaskQueue.php'; /** * @param \Swoole\Http\Server $server @@ -54,8 +54,8 @@ public static function make($server, string $version): Queue public static function stub(string $version): string { return static::hasBreakingChanges($version) - ? __DIR__.'/../../stubs/5.7/SwooleTaskQueue.stub' - : __DIR__.'/../../stubs/5.6/SwooleTaskQueue.stub'; + ? __DIR__ . '/../../stubs/5.7/SwooleTaskQueue.stub' + : __DIR__ . '/../../stubs/5.6/SwooleTaskQueue.stub'; } /** diff --git a/src/Task/SwooleTaskQueue.php b/src/Task/SwooleTaskQueue.php index 760b9345..6d2fb32c 100644 --- a/src/Task/SwooleTaskQueue.php +++ b/src/Task/SwooleTaskQueue.php @@ -54,7 +54,7 @@ public function push($job, $data = '', $queue = null) */ public function pushRaw($payload, $queue = null, array $options = []) { - return $this->swoole->task($payload, ! is_numeric($queue) ? 1 : (int)$queue); + return $this->swoole->task($payload, ! is_numeric($queue) ? 1 : (int) $queue); } /** diff --git a/src/Transformers/Request.php b/src/Transformers/Request.php index 2b48c6e1..eefd2bdf 100644 --- a/src/Transformers/Request.php +++ b/src/Transformers/Request.php @@ -3,6 +3,7 @@ namespace SwooleTW\Http\Transformers; use Illuminate\Http\Request as IlluminateRequest; +use Illuminate\Http\Response as IlluminateResponse; use Swoole\Http\Request as SwooleRequest; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request as SymfonyRequest; @@ -12,7 +13,17 @@ */ class Request { - private const BLACK_LIST = ['php', 'htaccess', 'config']; + /** + * Blacklisted extensions + * + * @const array + */ + protected const EXTENSION_BLACKLIST = ['php', 'htaccess', 'config']; + + /** + * Extension mime types + */ + protected const EXTENSION_MIMES = ['js' => 'text/javascript', 'css' => 'text/css']; /** * @var \Illuminate\Http\Request @@ -28,29 +39,17 @@ class Request */ public static function make(SwooleRequest $swooleRequest) { - list( - $get, $post, $cookie, $files, $server, $content - ) - = static::toIlluminateParameters($swooleRequest); - - return new static($get, $post, $cookie, $files, $server, $content); + return new static(...static::toIlluminateParameters($swooleRequest)); } /** * Request constructor. * - * @param array $get - * @param array $post - * @param array $cookie - * @param array $files - * @param array $server - * @param string $content - * - * @throws \LogicException + * @param array $params provides GET, POST, COOKIE, FILES, SERVER, CONTENT */ - public function __construct(array $get, array $post, array $cookie, array $files, array $server, $content = null) + public function __construct(...$params) { - $this->createIlluminateRequest($get, $post, $cookie, $files, $server, $content); + $this->createIlluminateRequest(...$params); } /** @@ -126,12 +125,12 @@ public function getIlluminateRequest() */ protected static function toIlluminateParameters(SwooleRequest $request) { - $get = isset($request->get) ? $request->get : []; - $post = isset($request->post) ? $request->post : []; - $cookie = isset($request->cookie) ? $request->cookie : []; - $files = isset($request->files) ? $request->files : []; - $header = isset($request->header) ? $request->header : []; - $server = isset($request->server) ? $request->server : []; + $get = $request->get ?? []; + $post = $request->post ?? []; + $cookie = $request->cookie ?? []; + $files = $request->files ?? []; + $header = $request->header ?? []; + $server = $request->server ?? []; $server = static::transformServerParameters($server, $header); $content = $request->rawContent(); @@ -160,7 +159,7 @@ protected static function transformServerParameters(array $server, array $header $key = strtoupper($key); if (! in_array($key, ['REMOTE_ADDR', 'SERVER_PORT', 'HTTPS'])) { - $key = 'HTTP_'.$key; + $key = 'HTTP_' . $key; } $__SERVER[$key] = $value; @@ -176,32 +175,27 @@ protected static function transformServerParameters(array $server, array $header * @param \Swoole\Http\Response $swooleResponse * @param string $publicPath * - * @return boolean|null + * @return boolean */ public static function handleStatic($swooleRequest, $swooleResponse, string $publicPath) { $uri = $swooleRequest->server['request_uri'] ?? ''; - $extension = substr(strrchr($uri, '.'), 1); - if ($extension && in_array($extension, static::BLACK_LIST)) { - return null; - } + $extension = pathinfo($uri, PATHINFO_EXTENSION); + $fileName = $publicPath . $uri; - $filename = $publicPath.$uri; - if (! is_file($filename) || filesize($filename) === 0) { - return null; + if ($extension && in_array($extension, static::EXTENSION_BLACKLIST)) { + return false; } - $swooleResponse->status(200); - $mime = mime_content_type($filename); - if ($extension === 'js') { - $mime = 'text/javascript'; - } else { - if ($extension === 'css') { - $mime = 'text/css'; - } + if (! is_file($fileName) || ! filesize($fileName)) { + return false; } - $swooleResponse->header('Content-Type', $mime); - $swooleResponse->sendfile($filename); + + $contentType = mime_content_type($fileName); + + $swooleResponse->status(IlluminateResponse::HTTP_OK); + $swooleResponse->header('Content-Type', static::EXTENSION_MIMES[$contentType] ?? $contentType); + $swooleResponse->sendfile($fileName); return true; } diff --git a/src/Transformers/Response.php b/src/Transformers/Response.php index 6d7004e9..1f91e05c 100644 --- a/src/Transformers/Response.php +++ b/src/Transformers/Response.php @@ -158,7 +158,7 @@ public function getSwooleResponse() protected function setIlluminateResponse($illuminateResponse) { if (! $illuminateResponse instanceof SymfonyResponse) { - $content = (string)$illuminateResponse; + $content = (string) $illuminateResponse; $illuminateResponse = new IlluminateResponse($content); } diff --git a/src/Transformers/StreamedResponse.php b/src/Transformers/StreamedResponse.php new file mode 100644 index 00000000..31a5e59b --- /dev/null +++ b/src/Transformers/StreamedResponse.php @@ -0,0 +1,38 @@ +output; + } + + /** + * Set output buffer + * + * @param string $output + */ + public function setOutput(?string $output = null): void + { + $this->output = $output; + } +} \ No newline at end of file diff --git a/src/Websocket/Authenticatable.php b/src/Websocket/Authenticatable.php index 8d07e7bf..92276511 100644 --- a/src/Websocket/Authenticatable.php +++ b/src/Websocket/Authenticatable.php @@ -35,7 +35,7 @@ public function loginUsing(AuthenticatableContract $user) */ public function loginUsingId($userId) { - return $this->join(static::USER_PREFIX.$userId); + return $this->join(static::USER_PREFIX . $userId); } /** @@ -49,7 +49,7 @@ public function logout() return null; } - return $this->leave(static::USER_PREFIX.$userId); + return $this->leave(static::USER_PREFIX . $userId); } /** @@ -84,7 +84,7 @@ public function toUserId($userIds) $userIds = is_string($userIds) || is_integer($userIds) ? func_get_args() : $userIds; foreach ($userIds as $userId) { - $fds = $this->room->getClients(static::USER_PREFIX.$userId); + $fds = $this->room->getClients(static::USER_PREFIX . $userId); $this->to($fds); } @@ -120,7 +120,7 @@ public function getUserId() */ public function isUserIdOnline($userId) { - return ! empty($this->room->getClients(static::USER_PREFIX.$userId)); + return ! empty($this->room->getClients(static::USER_PREFIX . $userId)); } /** @@ -131,7 +131,7 @@ public function isUserIdOnline($userId) protected function checkUser($user) { if (! $user instanceOf AuthenticatableContract) { - throw new InvalidArgumentException('user object must implement '.AuthenticatableContract::class); + throw new InvalidArgumentException('user object must implement ' . AuthenticatableContract::class); } } } diff --git a/src/Websocket/Facades/Room.php b/src/Websocket/Facades/Room.php index 72f3122a..d09d7e82 100644 --- a/src/Websocket/Facades/Room.php +++ b/src/Websocket/Facades/Room.php @@ -3,6 +3,7 @@ namespace SwooleTW\Http\Websocket\Facades; use Illuminate\Support\Facades\Facade; +use SwooleTW\Http\Helpers\Alias; /** * Class Room @@ -16,6 +17,6 @@ class Room extends Facade */ protected static function getFacadeAccessor() { - return 'swoole.room'; + return Alias::ROOM; } } \ No newline at end of file diff --git a/src/Websocket/Middleware/DecryptCookies.php b/src/Websocket/Middleware/DecryptCookies.php index d199a703..2807ea1b 100644 --- a/src/Websocket/Middleware/DecryptCookies.php +++ b/src/Websocket/Middleware/DecryptCookies.php @@ -55,7 +55,7 @@ public function __construct(EncrypterContract $encrypter) */ public function disableFor($name) { - $this->except = array_merge($this->except, (array)$name); + $this->except = array_merge($this->except, (array) $name); } /** diff --git a/src/Websocket/Parser.php b/src/Websocket/Parser.php index d1722e22..b61c93c6 100644 --- a/src/Websocket/Parser.php +++ b/src/Websocket/Parser.php @@ -26,7 +26,7 @@ public function execute($server, $frame) foreach ($this->strategies as $strategy) { $result = App::call( - $strategy.'@handle', + $strategy . '@handle', [ 'server' => $server, 'frame' => $frame, diff --git a/src/Websocket/Push.php b/src/Websocket/Push.php index 531a7e3e..50323fc8 100644 --- a/src/Websocket/Push.php +++ b/src/Websocket/Push.php @@ -55,7 +55,7 @@ class Push * @param string $event * @param string|null $message */ - private function __construct( + protected function __construct( int $opcode, int $sender, array $descriptors, @@ -63,7 +63,8 @@ private function __construct( bool $assigned, string $event, string $message = null - ) { + ) + { $this->opcode = $opcode; $this->sender = $sender; $this->descriptors = $descriptors; diff --git a/src/Websocket/Rooms/TableRoom.php b/src/Websocket/Rooms/TableRoom.php index a02091e2..163167f7 100644 --- a/src/Websocket/Rooms/TableRoom.php +++ b/src/Websocket/Rooms/TableRoom.php @@ -201,7 +201,7 @@ public function getValue(string $key, string $table) $value = $this->$table->get($key); - return $value ? json_decode($value['value'], true) : []; + return $value ? \json_decode($value['value'], true) : []; } /** diff --git a/src/Websocket/SocketIO/Packet.php b/src/Websocket/SocketIO/Packet.php index 5da3f021..f1f34ae4 100644 --- a/src/Websocket/SocketIO/Packet.php +++ b/src/Websocket/SocketIO/Packet.php @@ -118,7 +118,7 @@ public static function getSocketType(string $packet) return null; } - return (int)$type; + return (int) $type; } /** diff --git a/src/Websocket/SocketIO/SocketIOParser.php b/src/Websocket/SocketIO/SocketIOParser.php index 3c259bcf..53483fb4 100644 --- a/src/Websocket/SocketIO/SocketIOParser.php +++ b/src/Websocket/SocketIO/SocketIOParser.php @@ -27,12 +27,12 @@ class SocketIOParser extends Parser */ public function encode(string $event, $data) { - $packet = Packet::MESSAGE.Packet::EVENT; + $packet = Packet::MESSAGE . Packet::EVENT; $shouldEncode = is_array($data) || is_object($data); $data = $shouldEncode ? json_encode($data) : $data; $format = $shouldEncode ? '["%s",%s]' : '["%s","%s"]'; - return $packet.sprintf($format, $event, $data); + return $packet . sprintf($format, $event, $data); } /** diff --git a/src/Websocket/SocketIO/WebsocketHandler.php b/src/Websocket/SocketIO/WebsocketHandler.php index d76b60af..69319692 100644 --- a/src/Websocket/SocketIO/WebsocketHandler.php +++ b/src/Websocket/SocketIO/WebsocketHandler.php @@ -6,6 +6,7 @@ use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\Config; use Swoole\Websocket\Frame; +use SwooleTW\Http\Server\Facades\Server; use SwooleTW\Http\Websocket\HandlerContract; class WebsocketHandler implements HandlerContract @@ -29,11 +30,11 @@ public function onOpen($fd, Request $request) 'pingTimeout' => Config::get('swoole_websocket.ping_timeout'), ] ); - $initPayload = Packet::OPEN.$payload; - $connectPayload = Packet::MESSAGE.Packet::CONNECT; + $initPayload = Packet::OPEN . $payload; + $connectPayload = Packet::MESSAGE . Packet::CONNECT; - App::make('swoole.server')->push($fd, $initPayload); - App::make('swoole.server')->push($fd, $connectPayload); + App::make(Server::class)->push($fd, $initPayload); + App::make(Server::class)->push($fd, $connectPayload); return true; } diff --git a/src/Websocket/Websocket.php b/src/Websocket/Websocket.php index b945d02b..2ef95179 100644 --- a/src/Websocket/Websocket.php +++ b/src/Websocket/Websocket.php @@ -7,8 +7,12 @@ use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\Config; use InvalidArgumentException; +use SwooleTW\Http\Server\Facades\Server; use SwooleTW\Http\Websocket\Rooms\RoomContract; +/** + * Class Websocket + */ class Websocket { use Authenticatable; @@ -66,11 +70,18 @@ class Websocket */ protected $room; + /** + * DI Container. + * + * @var \Illuminate\Contracts\Container\Container + */ + protected $container; + /** * Websocket constructor. * - * @var RoomContract $room - * @var PipelineContract $pipeline + * @param \SwooleTW\Http\Websocket\Rooms\RoomContract $room + * @param \Illuminate\Contracts\Pipeline\Pipeline $pipeline */ public function __construct(RoomContract $room, PipelineContract $pipeline) { @@ -161,23 +172,21 @@ public function emit(string $event, $data): bool return false; } - $result = App::make('swoole.server')->task( - [ - 'action' => static::PUSH_ACTION, - 'data' => [ - 'sender' => $this->sender, - 'fds' => $fds, - 'broadcast' => $this->isBroadcast, - 'assigned' => $assigned, - 'event' => $event, - 'message' => $data, - ], - ] - ); + $result = App::make(Server::class)->task([ + 'action' => static::PUSH_ACTION, + 'data' => [ + 'sender' => $this->sender, + 'fds' => $fds, + 'broadcast' => $this->isBroadcast, + 'assigned' => $assigned, + 'event' => $event, + 'message' => $data, + ], + ]); $this->reset(); - return $result === false ? false : true; + return $result !== false; } /** @@ -250,13 +259,10 @@ public function call(string $event, $data = null) $data = $this->setRequestThroughMiddleware($data); } - return App::call( - $this->callbacks[$event], - [ - 'websocket' => $this, - $dataKey => $data, - ] - ); + return App::call($this->callbacks[$event], [ + 'websocket' => $this, + $dataKey => $data, + ]); } /** @@ -268,7 +274,7 @@ public function call(string $event, $data = null) */ public function close(int $fd = null) { - return App::make('swoole.server')->close($fd ?: $this->sender); + return App::make(Server::class)->close($fd ?: $this->sender); } /** diff --git a/tests/Server/ManagerTest.php b/tests/Server/ManagerTest.php index 4c9d41b8..fd1c42bb 100644 --- a/tests/Server/ManagerTest.php +++ b/tests/Server/ManagerTest.php @@ -11,6 +11,8 @@ use Swoole\Http\Request; use Swoole\Http\Response; use Swoole\Table; +use SwooleTW\Http\Helpers\Alias; +use SwooleTW\Http\Server\Facades\Server; use SwooleTW\Http\Server\Manager; use SwooleTW\Http\Server\Sandbox; use SwooleTW\Http\Table\SwooleTable; @@ -145,10 +147,10 @@ public function testOnWorkerStart() $manager->onWorkerStart($server); $app = $manager->getApplication(); - $this->assertTrue($app->make('swoole.sandbox') instanceof Sandbox); + $this->assertTrue($app->make(Sandbox::class) instanceof Sandbox); $this->assertTrue($app->make('swoole.table') instanceof SwooleTable); $this->assertTrue($app->make('swoole.room') instanceof RoomContract); - $this->assertTrue($app->make('swoole.websocket') instanceof Websocket); + $this->assertTrue($app->make(Websocket::class) instanceof Websocket); } public function testLoadApplication() @@ -192,7 +194,7 @@ public function testOnRequest() $container->singleton('events', function () { return $this->getEvent('swoole.request', false); }); - $container->singleton('swoole.websocket', function () { + $container->singleton(Websocket::class, function () { $websocket = m::mock(Websocket::class); $websocket->shouldReceive('reset') ->with(true) @@ -200,7 +202,7 @@ public function testOnRequest() return $websocket; }); - $container->singleton('swoole.sandbox', function () { + $container->singleton(Sandbox::class, function () { $sandbox = m::mock(Sandbox::class); $sandbox->shouldReceive('setRequest') ->with(m::type('Illuminate\Http\Request')) @@ -216,6 +218,8 @@ public function testOnRequest() return $sandbox; }); + $container->alias(Sandbox::class, 'swoole.sandbox'); + $this->mockMethod('base_path', function () { return '/'; }); @@ -250,13 +254,16 @@ public function testOnRequestException() $container->singleton('events', function () { return $this->getEvent('swoole.request', false); }); - $container->singleton('swoole.sandbox', function () { + $container->singleton(Sandbox::class, function () { $sandbox = m::mock(Sandbox::class); $sandbox->shouldReceive('disable') ->once(); return $sandbox; }); + + $container->alias(Sandbox::class, 'swoole.sandbox'); + $container->singleton(ExceptionHandler::class, function () { $handler = m::mock(ExceptionHandler::class); $handler->shouldReceive('render') @@ -365,7 +372,7 @@ public function testOnOpen() $request->fd = 1; $container = $this->getContainer(); - $container->singleton('swoole.websocket', function () { + $container->singleton(Websocket::class, function () { $websocket = m::mock(Websocket::class); $websocket->shouldReceive('reset') ->with(true) @@ -387,7 +394,7 @@ public function testOnOpen() return $websocket; }); - $container->singleton('swoole.sandbox', function () { + $container->singleton(Sandbox::class, function () { $sandbox = m::mock(Sandbox::class); $sandbox->shouldReceive('setRequest') ->with(m::type('Illuminate\Http\Request')) @@ -403,6 +410,8 @@ public function testOnOpen() return $sandbox; }); + $container->alias(Sandbox::class, 'swoole.sandbox'); + $handler = m::mock(HandlerContract::class); $handler->shouldReceive('onOpen') ->with(1, m::type('Illuminate\Http\Request')) @@ -433,7 +442,7 @@ public function testOnMessage() ]); $container = $this->getContainer(); - $container->singleton('swoole.websocket', function () use ($payload) { + $container->singleton(Websocket::class, function () use ($payload) { $websocket = m::mock(Websocket::class); $websocket->shouldReceive('reset') ->with(true) @@ -452,7 +461,7 @@ public function testOnMessage() return $websocket; }); - $container->singleton('swoole.sandbox', function () { + $container->singleton(Sandbox::class, function () { $sandbox = m::mock(Sandbox::class); $sandbox->shouldReceive('enable') ->once(); @@ -462,6 +471,8 @@ public function testOnMessage() return $sandbox; }); + $container->alias(Sandbox::class, 'swoole.sandbox'); + $manager = $this->getWebsocketManager(); $manager->setApplication($container); $manager->setPayloadParser($parser); @@ -472,7 +483,7 @@ public function testOnClose() { $fd = 1; $app = $this->getContainer(); - $app->singleton('swoole.websocket', function () use ($fd) { + $app->singleton(Websocket::class, function () use ($fd) { $websocket = m::mock(Websocket::class); $websocket->shouldReceive('reset') ->with(true) @@ -498,7 +509,7 @@ public function testOnClose() $server->shouldReceive('on'); $container = $this->getContainer($server); - $container->singleton('swoole.server', function () use ($fd) { + $container->singleton(Server::class, function () use ($fd) { $server = m::mock('server'); $server->shouldReceive('on'); $server->taskworker = false; @@ -513,6 +524,8 @@ public function testOnClose() return $server; }); + $container->alias(Server::class, Alias::SERVER); + $manager = $this->getWebsocketManager($container); $manager->setApplication($app); $manager->onClose('server', $fd, 'reactorId'); @@ -587,9 +600,10 @@ protected function getContainer($server = null, $config = null) $container->singleton('config', function () use ($config) { return $config; }); - $container->singleton('swoole.server', function () use ($server) { + $container->singleton(Server::class, function () use ($server) { return $server; }); + $container->alias(Server::class, Alias::SERVER); $container->singleton(ExceptionHandler::class, Handler::class); return $container; diff --git a/tests/SocketIO/WebsocketHandlerTest.php b/tests/SocketIO/WebsocketHandlerTest.php index 7cd011f8..c83bed2c 100644 --- a/tests/SocketIO/WebsocketHandlerTest.php +++ b/tests/SocketIO/WebsocketHandlerTest.php @@ -8,6 +8,7 @@ use Illuminate\Support\Facades\Config; use Mockery as m; use Swoole\Websocket\Frame; +use SwooleTW\Http\Server\Facades\Server; use SwooleTW\Http\Tests\TestCase; use SwooleTW\Http\Websocket\SocketIO\WebsocketHandler; @@ -37,7 +38,7 @@ public function testOnOpen() }, 'SwooleTW\Http\Websocket\SocketIO'); App::shouldReceive('make') - ->with('swoole.server') + ->with(Server::class) ->twice() ->andReturnSelf(); App::shouldReceive('push') diff --git a/tests/Transformers/RequestTest.php b/tests/Transformers/RequestTest.php index d68555d1..d89bf7db 100644 --- a/tests/Transformers/RequestTest.php +++ b/tests/Transformers/RequestTest.php @@ -69,7 +69,7 @@ public function testHandleStaticWithBlackList() $request->server['request_uri'] = 'foo.php'; $result = Request::handleStatic($request, null, '/'); - $this->assertNull($result); + $this->assertFalse($result); } public function testHandleStaticWithNoneFile() @@ -82,7 +82,7 @@ public function testHandleStaticWithNoneFile() }); $result = Request::handleStatic(new SwooleRequestStub, null, '/'); - $this->assertNull($result); + $this->assertFalse($result); $this->assertTrue($isFile); } diff --git a/tests/Websocket/WebsocketTest.php b/tests/Websocket/WebsocketTest.php index 5341b124..3541bfb6 100644 --- a/tests/Websocket/WebsocketTest.php +++ b/tests/Websocket/WebsocketTest.php @@ -11,6 +11,7 @@ use Illuminate\Support\Facades\Config; use InvalidArgumentException; use Mockery as m; +use SwooleTW\Http\Server\Facades\Server; use SwooleTW\Http\Tests\TestCase; use SwooleTW\Http\Websocket\Rooms\RoomContract; use SwooleTW\Http\Websocket\Websocket; @@ -327,7 +328,7 @@ public function testEmit() ->andReturn([3, 4, 5]); App::shouldReceive('make') - ->with('swoole.server') + ->with(Server::class) ->once() ->andReturnSelf(); @@ -360,7 +361,7 @@ public function testClose() $fd = 1; App::shouldReceive('make') - ->with('swoole.server') + ->with(Server::class) ->once() ->andReturnSelf(); From 74cb96d257fdd82799d6849d5496e6044345b139 Mon Sep 17 00:00:00 2001 From: liangping Date: Tue, 25 Dec 2018 10:19:37 +0800 Subject: [PATCH 020/161] Fix Swoole's default srcWorkerId should be -1 --- stubs/5.6/SwooleTaskQueue.stub | 2 +- stubs/5.7/SwooleTaskQueue.stub | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/stubs/5.6/SwooleTaskQueue.stub b/stubs/5.6/SwooleTaskQueue.stub index be9a2422..82c161d4 100644 --- a/stubs/5.6/SwooleTaskQueue.stub +++ b/stubs/5.6/SwooleTaskQueue.stub @@ -55,7 +55,7 @@ class SwooleTaskQueue extends Queue implements QueueContract */ public function pushRaw($payload, $queue = null, array $options = []) { - return $this->swoole->task($payload, !is_numeric($queue) ? 1 : (int)$queue); + return $this->swoole->task($payload, !is_numeric($queue) ? -1 : (int)$queue); } /** diff --git a/stubs/5.7/SwooleTaskQueue.stub b/stubs/5.7/SwooleTaskQueue.stub index 0a28fedf..b71d2f01 100644 --- a/stubs/5.7/SwooleTaskQueue.stub +++ b/stubs/5.7/SwooleTaskQueue.stub @@ -55,7 +55,7 @@ class SwooleTaskQueue extends Queue implements QueueContract */ public function pushRaw($payload, $queue = null, array $options = []) { - return $this->swoole->task($payload, !is_numeric($queue) ? 1 : (int)$queue); + return $this->swoole->task($payload, !is_numeric($queue) ? -1 : (int)$queue); } /** From 4387383f4032cef5f6729d3e1a0e5404d4cdc52c Mon Sep 17 00:00:00 2001 From: liangping Date: Tue, 25 Dec 2018 10:22:10 +0800 Subject: [PATCH 021/161] Fix remove backslash --- src/Task/SwooleTaskJob.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Task/SwooleTaskJob.php b/src/Task/SwooleTaskJob.php index 526c8e03..5aa0fc64 100644 --- a/src/Task/SwooleTaskJob.php +++ b/src/Task/SwooleTaskJob.php @@ -2,9 +2,9 @@ namespace SwooleTW\Http\Task; +use Illuminate\Queue\Jobs\Job; use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Queue\Job as JobContract; -use Illuminate\Queue\Jobs\Job; /** * Class SwooleTaskJob @@ -70,7 +70,7 @@ public function __construct(Container $container, $swoole, $job, $taskId, $srcWr public function fire() { if (method_exists($this, 'resolveAndFire')) { - $this->resolveAndFire(\json_decode($this->getRawBody(), true)); + $this->resolveAndFire(json_decode($this->getRawBody(), true)); } else { parent::fire(); } From aed922f141487cfe9dc084f098d81e5fe7fc1ac6 Mon Sep 17 00:00:00 2001 From: Fractal Zombie Date: Mon, 31 Dec 2018 04:08:13 +0200 Subject: [PATCH 022/161] More code refactoring. Fix for OS Helper. Added Hot Reload with FSWatch. --- composer.json | 3 +- config/swoole_http.php | 8 +- src/Commands/HttpServerCommand.php | 58 ++++++-- src/Concerns/ResetApplication.php | 3 +- src/Coroutine/Connectors/MySqlConnector.php | 1 + src/Coroutine/PDOStatement.php | 3 +- src/Helpers/OS.php | 6 +- src/HotReload/FSEvent.php | 138 ++++++++++++++++++++ src/HotReload/FSEventParser.php | 35 +++++ src/HotReload/FSProcess.php | 91 +++++++++++++ src/HttpServiceProvider.php | 13 +- src/Server/Manager.php | 11 ++ src/Websocket/Middleware/StartSession.php | 7 +- src/Websocket/Rooms/RedisRoom.php | 3 +- src/Websocket/Rooms/TableRoom.php | 7 +- tests/Server/ManagerTest.php | 7 +- tests/Server/ResettersTest.php | 6 +- tests/Server/SandboxTest.php | 2 +- tests/Websocket/TableRoomTest.php | 29 ++-- 19 files changed, 371 insertions(+), 60 deletions(-) create mode 100644 src/HotReload/FSEvent.php create mode 100644 src/HotReload/FSEventParser.php create mode 100644 src/HotReload/FSProcess.php diff --git a/composer.json b/composer.json index 6dd18845..4f593481 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,8 @@ "predis/predis": "^1.1", "ext-json": "*", "ext-fileinfo": "*", - "ext-pdo": "*" + "ext-pdo": "*", + "ext-pcntl": "*" }, "require-dev": { "laravel/lumen-framework": "~5.3", diff --git a/config/swoole_http.php b/config/swoole_http.php index a49fcb6b..ad6eaab7 100644 --- a/config/swoole_http.php +++ b/config/swoole_http.php @@ -59,11 +59,11 @@ |-------------------------------------------------------------------------- */ 'hot_reload' => [ - 'enabled' => env('SWOOLE_HOT_RELOAD_ENABLE', true), - 'level' => env('SWOOLE_HOT_RELOAD_DEEP_LEVEL', 10), - 'directory' => env('SWOOLE_HOT_RELOAD_DIRECTORY', base_path()), + 'enabled' => env('SWOOLE_HOT_RELOAD_ENABLE', false), + 'recursively' => env('SWOOLE_HOT_RELOAD_RECURSIVELY', true), + 'directory' => env('SWOOLE_HOT_RELOAD_DIRECTORY', base_path('app')), 'log' => env('SWOOLE_HOT_RELOAD_LOG', true), - 'files' => ['*.php'], + 'filter' => env('SWOOLE_HOT_RELOAD_FILTER', '.php'), ], /* diff --git a/src/Commands/HttpServerCommand.php b/src/Commands/HttpServerCommand.php index 33ebe8eb..09de6467 100644 --- a/src/Commands/HttpServerCommand.php +++ b/src/Commands/HttpServerCommand.php @@ -5,6 +5,10 @@ use Illuminate\Console\Command; use Illuminate\Support\Arr; use Swoole\Process; +use SwooleTW\Http\Helpers\Alias; +use SwooleTW\Http\HotReload\FSEvent; +use SwooleTW\Http\HotReload\FSProcess; +use SwooleTW\Http\Server\Facades\Server; use SwooleTW\Http\Server\Manager; use Throwable; @@ -67,7 +71,7 @@ public function handle() */ protected function loadConfigs() { - $this->config = $this->laravel->make('config')->get('swoole_http'); + $this->config = $this->laravel->make(Alias::CONFIG)->get('swoole_http'); } /** @@ -91,6 +95,7 @@ protected function start() $host = Arr::get($this->config, 'server.host'); $port = Arr::get($this->config, 'server.port'); + $hotReloadEnabled = Arr::get($this->config, 'hot_reload.enabled'); $this->info('Starting swoole http server...'); $this->info("Swoole http server started: "); @@ -101,7 +106,14 @@ protected function start() ); } - $this->laravel->make(Manager::class)->run(); + $manager = $this->laravel->make(Manager::class); + $server = $this->laravel->make(Server::class); + + if ($hotReloadEnabled) { + $manager->addProcess($this->getHotReloadProcess($server)); + } + + $manager->run(); } /** @@ -231,6 +243,26 @@ protected function initAction() } } + /** + * @param \SwooleTW\Http\Server\Facades\Server $server + * + * @return \Swoole\Process + */ + protected function getHotReloadProcess($server) + { + $recursively = Arr::get($this->config, 'hot_reload.recursively'); + $directory = Arr::get($this->config, 'hot_reload.directory'); + $filter = Arr::get($this->config, 'hot_reload.filter'); + $log = Arr::get($this->config, 'hot_reload.log'); + + $cb = function (FSEvent $event) use ($server, $log) { + $log ? $this->info($event->getPath()) : null; + $server->reload(); + }; + + return (new FSProcess($filter, $recursively, $directory))->make($cb); + } + /** * If Swoole process is running. * @@ -333,19 +365,19 @@ protected function checkEnvironment() if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { $this->error("Swoole extension doesn't support Windows OS yet."); - return; - } else { - if (! extension_loaded('swoole')) { - $this->error("Can't detect Swoole extension installed."); + exit(1); + } - return; - } else { - if (! version_compare(swoole_version(), '4.0.0', 'ge')) { - $this->error("Your Swoole version must be higher than 4.0 to use coroutine."); + if (! extension_loaded('swoole')) { + $this->error("Can't detect Swoole extension installed."); - return; - } - } + exit(1); + } + + if (! version_compare(swoole_version(), '4.0.0', 'ge')) { + $this->error("Your Swoole version must be higher than 4.0 to use coroutine."); + + exit(1); } } } diff --git a/src/Concerns/ResetApplication.php b/src/Concerns/ResetApplication.php index 3fcb9af2..d6a49593 100644 --- a/src/Concerns/ResetApplication.php +++ b/src/Concerns/ResetApplication.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http\Concerns; +use Illuminate\Contracts\Config\Repository; use Illuminate\Contracts\Container\Container; use SwooleTW\Http\Exceptions\SandboxException; use SwooleTW\Http\Server\Resetters\ResetterContract; @@ -28,7 +29,7 @@ trait ResetApplication */ protected function setInitialConfig() { - $this->config = clone $this->getBaseApp()->make('config'); + $this->config = clone $this->getBaseApp()->make(Repository::class); } /** diff --git a/src/Coroutine/Connectors/MySqlConnector.php b/src/Coroutine/Connectors/MySqlConnector.php index 2efa720a..7082d761 100644 --- a/src/Coroutine/Connectors/MySqlConnector.php +++ b/src/Coroutine/Connectors/MySqlConnector.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http\Coroutine\Connectors; + use Illuminate\Database\Connectors\MySqlConnector as BaseConnector; use Illuminate\Support\Str; use SwooleTW\Http\Coroutine\PDO as SwoolePDO; diff --git a/src/Coroutine/PDOStatement.php b/src/Coroutine/PDOStatement.php index 2ebae9b8..fcd605ab 100644 --- a/src/Coroutine/PDOStatement.php +++ b/src/Coroutine/PDOStatement.php @@ -236,7 +236,8 @@ public function fetch( /** * Returns a single column from the next row of a result set or FALSE if there are no more rows. * - * @param int $column_number + * @param int|null $columnNumber + * * 0-indexed number of the column you wish to retrieve from the row. * If no value is supplied, PDOStatement::fetchColumn() fetches the first column. * diff --git a/src/Helpers/OS.php b/src/Helpers/OS.php index 8f33cde7..d1541639 100644 --- a/src/Helpers/OS.php +++ b/src/Helpers/OS.php @@ -21,7 +21,7 @@ final class OS * * @const string */ - public const LINUX = 'linux'; + public const LINUX = 'lin'; /** * Linux @@ -39,7 +39,7 @@ final class OS */ public static function is(string ...$types): bool { - return \in_array(static::current(), $types, true); + return Str::contains(static::current(), $types); } /** @@ -49,6 +49,6 @@ public static function is(string ...$types): bool */ public static function current(): string { - return Str::lower(PHP_OS); + return Str::substr(Str::lower(PHP_OS), 0, 3); } } \ No newline at end of file diff --git a/src/HotReload/FSEvent.php b/src/HotReload/FSEvent.php new file mode 100644 index 00000000..b888dc9c --- /dev/null +++ b/src/HotReload/FSEvent.php @@ -0,0 +1,138 @@ +when = $when; + $this->path = $path; + $this->types = $types; + } + + /** + * @return \Illuminate\Support\Carbon + */ + public function getWhen(): Carbon + { + return $this->when; + } + + /** + * @return string + */ + public function getPath(): string + { + return $this->path; + } + + /** + * @return array + */ + public function getTypes(): array + { + return $this->types; + } + + /** + * Checks if event types has needed type(s) + * + * @param string ...$types + * + * @return bool + */ + public function isType(string ...$types): bool + { + return count(array_intersect($this->types, $types)) > 0; + } +} \ No newline at end of file diff --git a/src/HotReload/FSEventParser.php b/src/HotReload/FSEventParser.php new file mode 100644 index 00000000..365e315f --- /dev/null +++ b/src/HotReload/FSEventParser.php @@ -0,0 +1,35 @@ +filter = $filter; + $this->recursively = $recursively; + $this->directory = $directory; + $this->locked = false; + } + + /** + * Make swoole process + * + * @param callable|null $callback + * + * @return \Swoole\Process + */ + public function make(?callable $callback = null) + { + $mcb = function ($type, $buffer) use ($callback) { + if (AppProcess::OUT === $type && $event = FSEventParser::toEvent($buffer)) { + $this->locked = true; + ($callback) ? $callback($event) : null; + $this->locked = false; + unset($event); + } + }; + + return new SwooleProcess(function () use ($mcb) { + (new AppProcess($this->configure()))->run($mcb); + }, false, false); + } + + protected function configure(): array + { + return [ + 'fswatch', + $this->recursively ? '-rtx' : 'tx', + '-e', + '.*', + '-i', + "\\{$this->filter}$", + $this->directory, + ]; + } +} diff --git a/src/HttpServiceProvider.php b/src/HttpServiceProvider.php index 9fc3a762..84103ebb 100644 --- a/src/HttpServiceProvider.php +++ b/src/HttpServiceProvider.php @@ -3,7 +3,7 @@ namespace SwooleTW\Http; use Illuminate\Database\DatabaseManager; -use Illuminate\Queue\Capsule\Manager; +use Illuminate\Queue\QueueManager; use Illuminate\Support\Arr; use Illuminate\Support\ServiceProvider; use Swoole\Http\Server as HttpServer; @@ -199,11 +199,12 @@ protected function registerDatabaseDriver() */ protected function getMergedDatabaseConfig(array $config, string $name) { - $config = Arr::add($config, 'name', $name); - $config = array_merge($config, Arr::get($config, 'read', [])); - $config = array_merge($config, Arr::get($config, 'write', [])); + $newConfig = $config; + $newConfig = Arr::add($newConfig, 'name', $name); + $newConfig = array_merge($newConfig, Arr::get($newConfig, 'read', [])); + $newConfig = array_merge($newConfig, Arr::get($newConfig, 'write', [])); - return $config; + return $newConfig; } /** @@ -223,7 +224,7 @@ protected function getNewMySqlConnection(array $config) */ protected function registerSwooleQueueDriver() { - $this->app->afterResolving(Alias::QUEUE, function (Manager $manager) { + $this->app->afterResolving(Alias::QUEUE, function (QueueManager $manager) { $manager->addConnector('swoole', function () { return new SwooleTaskConnector($this->app->make(Server::class)); }); diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 72ecde05..1f6426ea 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -8,6 +8,7 @@ use Illuminate\Events\Dispatcher; use Illuminate\Support\Facades\Facade; use Illuminate\Support\Str; +use Swoole\Process; use SwooleTW\Http\Concerns\InteractsWithSwooleTable; use SwooleTW\Http\Concerns\InteractsWithWebsocket; use SwooleTW\Http\Concerns\WithApplication; @@ -392,6 +393,16 @@ protected function setProcessName($process) swoole_set_process_name($name); } + /** + * Add process to http server + * + * @param \Swoole\Process $process + */ + public function addProcess(Process $process): void + { + $this->container->make(Server::class)->addProcess($process); + } + /** * Indicates if it's in phpunit environment. * diff --git a/src/Websocket/Middleware/StartSession.php b/src/Websocket/Middleware/StartSession.php index 332dfdb0..a487f237 100644 --- a/src/Websocket/Middleware/StartSession.php +++ b/src/Websocket/Middleware/StartSession.php @@ -6,6 +6,7 @@ use Illuminate\Contracts\Session\Session; use Illuminate\Http\Request; use Illuminate\Session\SessionManager; +use Illuminate\Support\Arr; /** * Class StartSession @@ -42,9 +43,7 @@ public function __construct(SessionManager $manager) public function handle($request, Closure $next) { if ($this->sessionConfigured()) { - $request->setLaravelSession( - $session = $this->startSession($request) - ); + $request->setLaravelSession($this->startSession($request)); } return $next($request); @@ -87,6 +86,6 @@ public function getSession(Request $request) */ protected function sessionConfigured() { - return ! is_null($this->manager->getSessionConfig()['driver'] ?? null); + return Arr::get($this->manager->getSessionConfig(), 'session') !== null; } } diff --git a/src/Websocket/Rooms/RedisRoom.php b/src/Websocket/Rooms/RedisRoom.php index 16f28f35..d0d39fd4 100644 --- a/src/Websocket/Rooms/RedisRoom.php +++ b/src/Websocket/Rooms/RedisRoom.php @@ -240,8 +240,7 @@ public function getKey(string $key, string $table) */ protected function cleanRooms(): void { - $keys = $this->redis->keys("{$this->prefix}*"); - if (count($keys)) { + if (count($keys = $this->redis->keys("{$this->prefix}*"))) { $this->redis->del($keys); } } diff --git a/src/Websocket/Rooms/TableRoom.php b/src/Websocket/Rooms/TableRoom.php index 163167f7..4d97d78e 100644 --- a/src/Websocket/Rooms/TableRoom.php +++ b/src/Websocket/Rooms/TableRoom.php @@ -177,12 +177,7 @@ public function setValue($key, array $value, string $table) { $this->checkTable($table); - $this->$table->set( - $key, - [ - 'value' => json_encode($value), - ] - ); + $this->$table->set($key, ['value' => \json_encode($value)]); return $this; } diff --git a/tests/Server/ManagerTest.php b/tests/Server/ManagerTest.php index fd1c42bb..48453096 100644 --- a/tests/Server/ManagerTest.php +++ b/tests/Server/ManagerTest.php @@ -4,6 +4,7 @@ use Illuminate\Container\Container; +use Illuminate\Contracts\Config\Repository; use Illuminate\Contracts\Debug\ExceptionHandler; use Illuminate\Support\Facades\Config; use Laravel\Lumen\Exceptions\Handler; @@ -597,9 +598,11 @@ protected function getContainer($server = null, $config = null) $config = $config ?? $this->getConfig(); $container = new Container; - $container->singleton('config', function () use ($config) { + $container->singleton(Repository::class, function () use ($config) { return $config; }); + $container->alias(Repository::class, Alias::CONFIG); + $container->singleton(Server::class, function () use ($server) { return $server; }); @@ -621,7 +624,7 @@ protected function getServer() protected function getConfig($websocket = false) { - $config = m::mock('config'); + $config = m::mock(Repository::class); $settings = $websocket ? 'websocketConfig' : 'config'; $callback = function ($key) use ($settings) { return $this->$settings[$key] ?? ''; diff --git a/tests/Server/ResettersTest.php b/tests/Server/ResettersTest.php index d2675fcb..72bbffbd 100644 --- a/tests/Server/ResettersTest.php +++ b/tests/Server/ResettersTest.php @@ -4,10 +4,12 @@ use Illuminate\Container\Container; +use Illuminate\Contracts\Config\Repository; use Illuminate\Contracts\Http\Kernel; use Illuminate\Http\Request; use Illuminate\Support\ServiceProvider; use Mockery as m; +use SwooleTW\Http\Helpers\Alias; use SwooleTW\Http\Server\Resetters\BindRequest; use SwooleTW\Http\Server\Resetters\ClearInstances; use SwooleTW\Http\Server\Resetters\RebindKernelContainer; @@ -157,7 +159,7 @@ public function testRebindViewContainer() public function testResetConfig() { - $config = m::mock('config'); + $config = m::mock(Repository::class); $sandbox = m::mock(Sandbox::class); $sandbox->shouldReceive('getConfig') ->once() @@ -167,7 +169,7 @@ public function testResetConfig() $resetter = new ResetConfig; $app = $resetter->handle($container, $sandbox); - $this->assertSame(get_class($config), get_class($app->make('config'))); + $this->assertSame(get_class($config), get_class($app->make(Alias::CONFIG))); } public function testResetCookie() diff --git a/tests/Server/SandboxTest.php b/tests/Server/SandboxTest.php index ee4e02cf..0a110cfd 100644 --- a/tests/Server/SandboxTest.php +++ b/tests/Server/SandboxTest.php @@ -63,7 +63,7 @@ public function testInitialize() $container = m::mock(Container::class); $container->shouldReceive('make') - ->with('config') + ->with(\Illuminate\Contracts\Config\Repository::class) ->once() ->andReturn($config); $container->shouldReceive('make') diff --git a/tests/Websocket/TableRoomTest.php b/tests/Websocket/TableRoomTest.php index b2df7d3a..a34fdaa1 100644 --- a/tests/Websocket/TableRoomTest.php +++ b/tests/Websocket/TableRoomTest.php @@ -5,6 +5,7 @@ use Swoole\Table; use SwooleTW\Http\Tests\TestCase; +use SwooleTW\Http\Websocket\Rooms\RoomContract; use SwooleTW\Http\Websocket\Rooms\TableRoom; class TableRoomTest extends TestCase @@ -48,7 +49,7 @@ public function testInvalidTableName() public function testSetValue() { - $this->tableRoom->setValue($key = 1, $value = ['foo', 'bar'], $table = 'fds'); + $this->tableRoom->setValue($key = 1, $value = ['foo', 'bar'], $table = RoomContract::DESCRIPTORS_KEY); $this->assertSame($value, $this->tableRoom->getValue($key, $table)); } @@ -57,17 +58,17 @@ public function testAddAll() { $this->tableRoom->add($key = 1, $values = ['foo', 'bar']); - $this->assertSame($values, $this->tableRoom->getValue($key, $table = 'fds')); - $this->assertSame([$key], $this->tableRoom->getValue('foo', 'rooms')); - $this->assertSame([$key], $this->tableRoom->getValue('bar', 'rooms')); + $this->assertSame($values, $this->tableRoom->getValue($key, $table = RoomContract::DESCRIPTORS_KEY)); + $this->assertSame([$key], $this->tableRoom->getValue('foo', RoomContract::ROOMS_KEY)); + $this->assertSame([$key], $this->tableRoom->getValue('bar', RoomContract::ROOMS_KEY)); } public function testAdd() { $this->tableRoom->add($key = 1, $value = 'foo'); - $this->assertSame([$value], $this->tableRoom->getValue($key, $table = 'fds')); - $this->assertSame([$key], $this->tableRoom->getValue($value, 'rooms')); + $this->assertSame([$value], $this->tableRoom->getValue($key, $table = RoomContract::DESCRIPTORS_KEY)); + $this->assertSame([$key], $this->tableRoom->getValue($value, RoomContract::ROOMS_KEY)); } public function testDeleteAll() @@ -75,9 +76,9 @@ public function testDeleteAll() $this->tableRoom->add($key = 1, $values = ['foo', 'bar']); $this->tableRoom->delete($key); - $this->assertSame([], $this->tableRoom->getValue($key, $table = 'fds')); - $this->assertSame([], $this->tableRoom->getValue('foo', 'rooms')); - $this->assertSame([], $this->tableRoom->getValue('bar', 'rooms')); + $this->assertSame([], $this->tableRoom->getValue($key, $table = RoomContract::DESCRIPTORS_KEY)); + $this->assertSame([], $this->tableRoom->getValue('foo', RoomContract::ROOMS_KEY)); + $this->assertSame([], $this->tableRoom->getValue('bar', RoomContract::ROOMS_KEY)); } public function testDelete() @@ -85,9 +86,9 @@ public function testDelete() $this->tableRoom->add($key = 1, $values = ['foo', 'bar']); $this->tableRoom->delete($key, 'foo'); - $this->assertSame(['bar'], $this->tableRoom->getValue($key, $table = 'fds')); - $this->assertSame([], $this->tableRoom->getValue('foo', 'rooms')); - $this->assertSame([$key], $this->tableRoom->getValue('bar', 'rooms')); + $this->assertSame(['bar'], $this->tableRoom->getValue($key, $table = RoomContract::DESCRIPTORS_KEY)); + $this->assertSame([], $this->tableRoom->getValue('foo', RoomContract::ROOMS_KEY)); + $this->assertSame([$key], $this->tableRoom->getValue('bar', RoomContract::ROOMS_KEY)); } public function testGetRooms() @@ -95,7 +96,7 @@ public function testGetRooms() $this->tableRoom->add($key = 1, $values = ['foo', 'bar']); $this->assertSame( - $this->tableRoom->getValue($key, $table = 'fds'), + $this->tableRoom->getValue($key, $table = RoomContract::DESCRIPTORS_KEY), $this->tableRoom->getRooms($key) ); } @@ -107,7 +108,7 @@ public function testGetClients() $this->tableRoom->add($keys[1], $room); $this->assertSame( - $this->tableRoom->getValue($room, $table = 'rooms'), + $this->tableRoom->getValue($room, $table = RoomContract::ROOMS_KEY), $this->tableRoom->getClients($room) ); } From ac0c514170f5056191697d5b37633d5d5f5382e1 Mon Sep 17 00:00:00 2001 From: Fractal Zombie Date: Mon, 31 Dec 2018 16:04:50 +0200 Subject: [PATCH 023/161] Added access log to console. Refactoring. --- config/swoole_http.php | 4 +- src/Commands/HttpServerCommand.php | 31 ++++++++++++- src/HotReload/FSEvent.php | 55 ++++++++++++++++++----- src/HotReload/FSEventParser.php | 3 ++ src/HotReload/FSOutput.php | 25 +++++++++++ src/HotReload/FSProcess.php | 21 ++++++--- src/HttpServiceProvider.php | 11 ++++- src/Middlewares/AccessLog.php | 54 +++++++++++++++++++++++ src/Server/AccessOutput.php | 71 ++++++++++++++++++++++++++++++ src/Server/Manager.php | 4 ++ 10 files changed, 256 insertions(+), 23 deletions(-) create mode 100644 src/HotReload/FSOutput.php create mode 100644 src/Middlewares/AccessLog.php create mode 100644 src/Server/AccessOutput.php diff --git a/config/swoole_http.php b/config/swoole_http.php index ad6eaab7..6825c532 100644 --- a/config/swoole_http.php +++ b/config/swoole_http.php @@ -15,7 +15,7 @@ 'public_path' => base_path('public'), // Determine if to use swoole to respond request for static files 'handle_static_files' => env('SWOOLE_HANDLE_STATIC', true), - 'log' => env('SWOOLE_HTTP_LOG', true), + 'access_log' => env('SWOOLE_HTTP_ACCESS_LOG', true), // You must add --enable-openssl while compiling Swoole // Put `SWOOLE_SOCK_TCP | SWOOLE_SSL` if you want to enable SSL 'socket_type' => SWOOLE_SOCK_TCP, @@ -61,7 +61,7 @@ 'hot_reload' => [ 'enabled' => env('SWOOLE_HOT_RELOAD_ENABLE', false), 'recursively' => env('SWOOLE_HOT_RELOAD_RECURSIVELY', true), - 'directory' => env('SWOOLE_HOT_RELOAD_DIRECTORY', base_path('app')), + 'directory' => env('SWOOLE_HOT_RELOAD_DIRECTORY', base_path()), 'log' => env('SWOOLE_HOT_RELOAD_LOG', true), 'filter' => env('SWOOLE_HOT_RELOAD_FILTER', '.php'), ], diff --git a/src/Commands/HttpServerCommand.php b/src/Commands/HttpServerCommand.php index 09de6467..cc148474 100644 --- a/src/Commands/HttpServerCommand.php +++ b/src/Commands/HttpServerCommand.php @@ -3,13 +3,19 @@ namespace SwooleTW\Http\Commands; use Illuminate\Console\Command; +use Illuminate\Console\OutputStyle; +use Illuminate\Contracts\Container\Container; use Illuminate\Support\Arr; use Swoole\Process; use SwooleTW\Http\Helpers\Alias; use SwooleTW\Http\HotReload\FSEvent; +use SwooleTW\Http\HotReload\FSOutput; use SwooleTW\Http\HotReload\FSProcess; +use SwooleTW\Http\Middlewares\AccessLog; +use SwooleTW\Http\Server\AccessOutput; use SwooleTW\Http\Server\Facades\Server; use SwooleTW\Http\Server\Manager; +use Symfony\Component\Console\Output\ConsoleOutput; use Throwable; /** @@ -96,6 +102,7 @@ protected function start() $host = Arr::get($this->config, 'server.host'); $port = Arr::get($this->config, 'server.port'); $hotReloadEnabled = Arr::get($this->config, 'hot_reload.enabled'); + $accessLogEnabled = Arr::get($this->config, 'server.access_log'); $this->info('Starting swoole http server...'); $this->info("Swoole http server started: "); @@ -109,6 +116,10 @@ protected function start() $manager = $this->laravel->make(Manager::class); $server = $this->laravel->make(Server::class); + if ($accessLogEnabled) { + $this->registerAccessLog(); + } + if ($hotReloadEnabled) { $manager->addProcess($this->getHotReloadProcess($server)); } @@ -256,7 +267,7 @@ protected function getHotReloadProcess($server) $log = Arr::get($this->config, 'hot_reload.log'); $cb = function (FSEvent $event) use ($server, $log) { - $log ? $this->info($event->getPath()) : null; + $log ? $this->info(FSOutput::format($event)) : null; $server->reload(); }; @@ -380,4 +391,22 @@ protected function checkEnvironment() exit(1); } } + + /** + * Register access log services. + */ + protected function registerAccessLog() + { + $this->laravel->singleton(OutputStyle::class, function () { + return new OutputStyle($this->input, $this->output); + }); + + $this->laravel->singleton(AccessOutput::class, function () { + return new AccessOutput(new ConsoleOutput()); + }); + + $this->laravel->singleton(AccessLog::class, function (Container $container) { + return new AccessLog($container->make(AccessOutput::class)); + }); + } } diff --git a/src/HotReload/FSEvent.php b/src/HotReload/FSEvent.php index b888dc9c..bf6c6bdb 100644 --- a/src/HotReload/FSEvent.php +++ b/src/HotReload/FSEvent.php @@ -2,85 +2,98 @@ namespace SwooleTW\Http\HotReload; +use Illuminate\Support\Arr; use Illuminate\Support\Carbon; /** * Class FSEvent + * + * @codeCoverageIgnore */ class FSEvent { /** - * Event - Created + * Event - Created. * * @var string */ public const Created = 'Created'; /** - * Event - Updated + * Event - Updated. * * @var string */ public const Updated = 'Updated'; /** - * Event - Removed + * Event - Removed. * * @var string */ public const Removed = 'Removed'; /** - * Event - Renamed + * Event - Renamed. * * @var string */ public const Renamed = 'Renamed'; /** - * Event - OwnerModified + * Event - OwnerModified. * * @var string */ public const OwnerModified = 'OwnerModified'; /** - * Event - AttributeModified + * Event - AttributeModified. * * @var string */ public const AttributeModified = 'AttributeModified'; /** - * Event - MovedFrom + * Event - MovedFrom. * * @var string */ public const MovedFrom = 'MovedFrom'; /** - * Event - MovedTo + * Event - MovedTo. * * @var string */ public const MovedTo = 'MovedTo'; /** - * When event fired + * Possible event types. + * + * @var array + */ + protected static $possibleTypes = [ + self::Created, self::Updated, self::Removed, self::Renamed, + self::OwnerModified, self::AttributeModified, self::MovedFrom, self::MovedTo, + ]; + + /** + * When event fired. * * @var \Illuminate\Support\Carbon */ protected $when; /** - * Directory or file path + * Directory or file path. * * @var string */ protected $path; /** - * Event types + * Event types. * * @var array */ @@ -125,7 +138,15 @@ public function getTypes(): array } /** - * Checks if event types has needed type(s) + * @return string + */ + public function getType(): string + { + return Arr::first($this->types); + } + + /** + * Checks if event types has needed type(s). * * @param string ...$types * @@ -135,4 +156,14 @@ public function isType(string ...$types): bool { return count(array_intersect($this->types, $types)) > 0; } + + /** + * Get possible event types. + * + * @return array + */ + public static function getPossibleTypes(): array + { + return self::$possibleTypes; + } } \ No newline at end of file diff --git a/src/HotReload/FSEventParser.php b/src/HotReload/FSEventParser.php index 365e315f..8b02fa25 100644 --- a/src/HotReload/FSEventParser.php +++ b/src/HotReload/FSEventParser.php @@ -6,6 +6,8 @@ /** * Class FSEventParser + * + * @codeCoverageIgnore */ class FSEventParser { @@ -26,6 +28,7 @@ public static function toEvent(string $event): ?FSEvent $date = Carbon::parse($matches[static::DATE]); $path = $matches[static::PATH]; $events = explode(' ', $matches[static::EVENTS]); + $events = array_sort(array_intersect(FSEvent::getPossibleTypes(), $events)); return new FSEvent($date, $path, $events); } diff --git a/src/HotReload/FSOutput.php b/src/HotReload/FSOutput.php new file mode 100644 index 00000000..b621503b --- /dev/null +++ b/src/HotReload/FSOutput.php @@ -0,0 +1,25 @@ +getPath()) ? 'Directory' : 'File'; + $events = implode(', ', $event->getTypes()); + $time = $event->getWhen()->format('H:i:s'); + + return sprintf('%s %s at %s', $item, $events, $time); + } +} \ No newline at end of file diff --git a/src/HotReload/FSProcess.php b/src/HotReload/FSProcess.php index 270af82f..b02bc26d 100644 --- a/src/HotReload/FSProcess.php +++ b/src/HotReload/FSProcess.php @@ -7,32 +7,34 @@ /** * Class FSProcess + * + * @codeCoverageIgnore */ class FSProcess { /** - * Observed files + * Observed files. * * @var array */ protected $filter; /** - * Watch recursively + * Watch recursively. * * @var string */ protected $recursively; /** - * Watch directory + * Watch directory. * * @var string */ protected $directory; /** - * When locked event cannot do anything + * When locked event cannot do anything. * * @var bool */ @@ -54,7 +56,7 @@ public function __construct(string $filter, string $recursively, string $directo } /** - * Make swoole process + * Make swoole process. * * @param callable|null $callback * @@ -72,15 +74,20 @@ public function make(?callable $callback = null) }; return new SwooleProcess(function () use ($mcb) { - (new AppProcess($this->configure()))->run($mcb); + (new AppProcess($this->configure()))->setTimeout(0)->run($mcb); }, false, false); } + /** + * Configure process. + * + * @return array + */ protected function configure(): array { return [ 'fswatch', - $this->recursively ? '-rtx' : 'tx', + $this->recursively ? '-rtx' : '-tx', '-e', '.*', '-i', diff --git a/src/HttpServiceProvider.php b/src/HttpServiceProvider.php index 84103ebb..af26c57e 100644 --- a/src/HttpServiceProvider.php +++ b/src/HttpServiceProvider.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http; +use Illuminate\Contracts\Http\Kernel; use Illuminate\Database\DatabaseManager; use Illuminate\Queue\QueueManager; use Illuminate\Support\Arr; @@ -13,6 +14,7 @@ use SwooleTW\Http\Coroutine\MySqlConnection; use SwooleTW\Http\Helpers\Alias; use SwooleTW\Http\Helpers\FW; +use SwooleTW\Http\Middlewares\AccessLog; use SwooleTW\Http\Server\Facades\Server; use SwooleTW\Http\Task\Connectors\SwooleTaskConnector; @@ -81,9 +83,16 @@ public function boot() __DIR__ . '/../routes/websocket.php' => base_path('routes/websocket.php'), ], 'laravel-swoole'); - if ($this->app->make(Alias::CONFIG)->get('swoole_http.websocket.enabled')) { + $config = $this->app->make(Alias::CONFIG); + + if ($config->get('swoole_http.websocket.enabled')) { $this->bootRoutes(); } + + if ($config->get('swoole_http.server.access_log')) { + $this->app->make(Kernel::class)->pushMiddleware(AccessLog::class); +// dd($this->app->make(Kernel::class)); + } } /** diff --git a/src/Middlewares/AccessLog.php b/src/Middlewares/AccessLog.php new file mode 100644 index 00000000..ab488050 --- /dev/null +++ b/src/Middlewares/AccessLog.php @@ -0,0 +1,54 @@ +output = $output; + } + + /** + * Handle the incoming request. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @return mixed + */ + public function handle($request, Closure $next) + { + return $next($request); + } + + /** + * Handle the outgoing request and response. + * + * @param \Illuminate\Http\Request $request + * @param \Illuminate\Http\Response $response + */ + public function terminate(Request $request, Response $response) + { + $this->output->log($request, $response); + } +} \ No newline at end of file diff --git a/src/Server/AccessOutput.php b/src/Server/AccessOutput.php new file mode 100644 index 00000000..c93ef64b --- /dev/null +++ b/src/Server/AccessOutput.php @@ -0,0 +1,71 @@ +output = $output; + } + + /** + * Access log. + * + * @param \Illuminate\Http\Request $request + * @param \Illuminate\Http\Response $response + */ + public function log(Request $request, Response $response): void + { + $host = $request->url(); + $method = $request->method(); + $agent = $request->userAgent(); + $date = $this->date($response->getDate()); + $status = $response->status(); + $style = $this->style($status); + + $this->output->writeln( + sprintf("%s %s %s <$style>%d %s", $host, $date, $method, $status, $agent) + ); + } + + /** + * @param \DateTimeInterface $date + * + * @return string + */ + protected function date(DateTimeInterface $date): string + { + return $date->format('Y-m-d H:i:s'); + } + + /** + * @param int $status + * + * @return string + */ + protected function style(int $status): string + { + return $status !== Response::HTTP_OK ? 'error' : 'info'; + } +} \ No newline at end of file diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 1f6426ea..dde9e084 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -3,6 +3,7 @@ namespace SwooleTW\Http\Server; use Exception; +use Illuminate\Console\OutputStyle; use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Debug\ExceptionHandler; use Illuminate\Events\Dispatcher; @@ -211,11 +212,14 @@ public function onRequest($swooleRequest, $swooleResponse) // set current request to sandbox $sandbox->setRequest($illuminateRequest); + // enable sandbox $sandbox->enable(); // handle request via laravel/lumen's dispatcher $illuminateResponse = $sandbox->run($illuminateRequest); + + // send response Response::make($illuminateResponse, $swooleResponse)->send(); } catch (Throwable $e) { try { From a15cf16dda3bdf11834ee5457b5ff15fdbfd740d Mon Sep 17 00:00:00 2001 From: Fractal Zombie Date: Mon, 31 Dec 2018 16:40:43 +0200 Subject: [PATCH 024/161] Added some tests. --- src/Commands/HttpServerCommand.php | 2 +- src/HotReload/FSEvent.php | 2 -- src/HotReload/FSEventParser.php | 2 -- tests/HotReload/FSEventParserTest.php | 22 +++++++++++++++++++++ tests/HotReload/FSEventTest.php | 28 +++++++++++++++++++++++++++ 5 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 tests/HotReload/FSEventParserTest.php create mode 100644 tests/HotReload/FSEventTest.php diff --git a/src/Commands/HttpServerCommand.php b/src/Commands/HttpServerCommand.php index cc148474..4422866f 100644 --- a/src/Commands/HttpServerCommand.php +++ b/src/Commands/HttpServerCommand.php @@ -402,7 +402,7 @@ protected function registerAccessLog() }); $this->laravel->singleton(AccessOutput::class, function () { - return new AccessOutput(new ConsoleOutput()); + return new AccessOutput(new ConsoleOutput); }); $this->laravel->singleton(AccessLog::class, function (Container $container) { diff --git a/src/HotReload/FSEvent.php b/src/HotReload/FSEvent.php index bf6c6bdb..d2052cfe 100644 --- a/src/HotReload/FSEvent.php +++ b/src/HotReload/FSEvent.php @@ -7,8 +7,6 @@ /** * Class FSEvent - * - * @codeCoverageIgnore */ class FSEvent { diff --git a/src/HotReload/FSEventParser.php b/src/HotReload/FSEventParser.php index 8b02fa25..70694c65 100644 --- a/src/HotReload/FSEventParser.php +++ b/src/HotReload/FSEventParser.php @@ -6,8 +6,6 @@ /** * Class FSEventParser - * - * @codeCoverageIgnore */ class FSEventParser { diff --git a/tests/HotReload/FSEventParserTest.php b/tests/HotReload/FSEventParserTest.php new file mode 100644 index 00000000..d89fd385 --- /dev/null +++ b/tests/HotReload/FSEventParserTest.php @@ -0,0 +1,22 @@ +assertInstanceOf(FSEvent::class, $event); + } +} \ No newline at end of file diff --git a/tests/HotReload/FSEventTest.php b/tests/HotReload/FSEventTest.php new file mode 100644 index 00000000..4df2d054 --- /dev/null +++ b/tests/HotReload/FSEventTest.php @@ -0,0 +1,28 @@ +assertTrue(array_diff($event->getTypes(), [FSEvent::Renamed, FSEvent::OwnerModified]) === []); + $this->assertTrue((new Carbon('Mon Dec 31 01:18:34 2018'))->eq($event->getWhen())); + $this->assertEquals('/Some/Path/To/File/File.php', $event->getPath()); + $this->assertTrue($event->isType(FSEvent::Renamed)); + $this->assertTrue($event->isType(FSEvent::OwnerModified)); + } +} \ No newline at end of file From 83635cbf2fe5495ec2c3d159df9a8e367e8e425c Mon Sep 17 00:00:00 2001 From: Fractal Zombie Date: Mon, 31 Dec 2018 16:52:23 +0200 Subject: [PATCH 025/161] Fix for Carbon. --- src/Coroutine/Connectors/MySqlConnector.php | 1 - src/HotReload/FSEvent.php | 8 +- src/HotReload/FSEventParser.php | 2 +- src/HotReload/FSOutput.php | 6 +- src/Middlewares/AccessLog.php | 5 +- src/Server/Manager.php | 1 - tests/Coroutine/ConnectorFactoryTest.php | 1 - tests/Coroutine/ContextTest.php | 1 - tests/HotReload/FSEventParserTest.php | 6 + tests/HotReload/FSEventTest.php | 2 +- tests/HotReload/FSOutputTest.php | 24 ++ tests/Server/ManagerTest.php | 209 +++++++++-------- tests/Server/ResettersTest.php | 71 +++--- tests/Server/SandboxTest.php | 37 ++- tests/SocketIO/PacketTest.php | 1 - tests/SocketIO/ParserTest.php | 3 +- tests/SocketIO/SocketIOControllerTest.php | 63 +++--- tests/SocketIO/WebsocketHandlerTest.php | 35 ++- tests/Table/TableTest.php | 1 - tests/Task/FakeJob.php | 1 - tests/Task/QueueFactoryTest.php | 1 - tests/Task/SwooleJobTest.php | 1 - tests/Task/SwooleQueueTest.php | 1 - tests/TestCase.php | 7 +- tests/Transformers/RequestTest.php | 13 +- tests/Transformers/ResponseTest.php | 1 - .../Websocket/Middleware/AuthenticateTest.php | 7 +- .../Middleware/DecrpytCookiesTest.php | 9 +- .../Websocket/Middleware/StartSessionTest.php | 1 - tests/Websocket/RedisRoomTest.php | 27 ++- tests/Websocket/SimpleParserTest.php | 1 - tests/Websocket/TableRoomTest.php | 1 - tests/Websocket/WebsocketTest.php | 211 +++++++++--------- tests/fixtures/bootstrap/app.php | 1 - .../app/Providers/RouteServiceProvider.php | 1 - .../app/Providers/TestServiceProvider.php | 1 - .../app/providers/TestServiceProvider.php | 1 - 37 files changed, 381 insertions(+), 382 deletions(-) create mode 100644 tests/HotReload/FSOutputTest.php diff --git a/src/Coroutine/Connectors/MySqlConnector.php b/src/Coroutine/Connectors/MySqlConnector.php index 7082d761..2efa720a 100644 --- a/src/Coroutine/Connectors/MySqlConnector.php +++ b/src/Coroutine/Connectors/MySqlConnector.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Coroutine\Connectors; - use Illuminate\Database\Connectors\MySqlConnector as BaseConnector; use Illuminate\Support\Str; use SwooleTW\Http\Coroutine\PDO as SwoolePDO; diff --git a/src/HotReload/FSEvent.php b/src/HotReload/FSEvent.php index d2052cfe..9ae55e93 100644 --- a/src/HotReload/FSEvent.php +++ b/src/HotReload/FSEvent.php @@ -3,7 +3,7 @@ namespace SwooleTW\Http\HotReload; use Illuminate\Support\Arr; -use Illuminate\Support\Carbon; +use Carbon\Carbon; /** * Class FSEvent @@ -79,7 +79,7 @@ class FSEvent /** * When event fired. * - * @var \Illuminate\Support\Carbon + * @var \Carbon\Carbon */ protected $when; @@ -100,7 +100,7 @@ class FSEvent /** * Event constructor. * - * @param \Illuminate\Support\Carbon $when + * @param \Carbon\Carbon $when * @param string $path * @param array $types */ @@ -112,7 +112,7 @@ public function __construct(Carbon $when, string $path, array $types) } /** - * @return \Illuminate\Support\Carbon + * @return \Carbon\Carbon */ public function getWhen(): Carbon { diff --git a/src/HotReload/FSEventParser.php b/src/HotReload/FSEventParser.php index 70694c65..d526030d 100644 --- a/src/HotReload/FSEventParser.php +++ b/src/HotReload/FSEventParser.php @@ -2,7 +2,7 @@ namespace SwooleTW\Http\HotReload; -use Illuminate\Support\Carbon; +use Carbon\Carbon; /** * Class FSEventParser diff --git a/src/HotReload/FSOutput.php b/src/HotReload/FSOutput.php index b621503b..d9fd5a3e 100644 --- a/src/HotReload/FSOutput.php +++ b/src/HotReload/FSOutput.php @@ -4,8 +4,6 @@ /** * Class FSOutput - * - * @codeCoverageIgnore */ class FSOutput { @@ -18,8 +16,8 @@ public static function format(FSEvent $event): string { $item = is_dir($event->getPath()) ? 'Directory' : 'File'; $events = implode(', ', $event->getTypes()); - $time = $event->getWhen()->format('H:i:s'); + $time = $event->getWhen()->format('Y.m.d H:i:s'); - return sprintf('%s %s at %s', $item, $events, $time); + return sprintf('%s: %s %s at %s', $item, $event->getPath(), $events, $time); } } \ No newline at end of file diff --git a/src/Middlewares/AccessLog.php b/src/Middlewares/AccessLog.php index ab488050..5cc0a4fa 100644 --- a/src/Middlewares/AccessLog.php +++ b/src/Middlewares/AccessLog.php @@ -32,8 +32,9 @@ public function __construct(AccessOutput $output) /** * Handle the incoming request. * - * @param \Illuminate\Http\Request $request - * @param \Closure $next + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * * @return mixed */ public function handle($request, Closure $next) diff --git a/src/Server/Manager.php b/src/Server/Manager.php index dde9e084..7d82e8ef 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -3,7 +3,6 @@ namespace SwooleTW\Http\Server; use Exception; -use Illuminate\Console\OutputStyle; use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Debug\ExceptionHandler; use Illuminate\Events\Dispatcher; diff --git a/tests/Coroutine/ConnectorFactoryTest.php b/tests/Coroutine/ConnectorFactoryTest.php index d47169f4..a18f9d83 100644 --- a/tests/Coroutine/ConnectorFactoryTest.php +++ b/tests/Coroutine/ConnectorFactoryTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\Coroutine; - use Illuminate\Support\Str; use SwooleTW\Http\Coroutine\Connectors\ConnectorFactory; use SwooleTW\Http\Helpers\FW; diff --git a/tests/Coroutine/ContextTest.php b/tests/Coroutine/ContextTest.php index d413482e..a9ef6800 100644 --- a/tests/Coroutine/ContextTest.php +++ b/tests/Coroutine/ContextTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\Coroutine; - use Illuminate\Container\Container; use Mockery as m; use SwooleTW\Http\Coroutine\Context; diff --git a/tests/HotReload/FSEventParserTest.php b/tests/HotReload/FSEventParserTest.php index d89fd385..33deea92 100644 --- a/tests/HotReload/FSEventParserTest.php +++ b/tests/HotReload/FSEventParserTest.php @@ -18,5 +18,11 @@ public function testItCanCreateObjectAfterParse() $event = FSEventParser::toEvent($buffer); $this->assertInstanceOf(FSEvent::class, $event); + + $this->assertTrue(array_diff($event->getTypes(), [FSEvent::Renamed, FSEvent::OwnerModified]) === []); + $this->assertTrue((new Carbon('Mon Dec 31 01:18:34 2018'))->eq($event->getWhen())); + $this->assertEquals('/Some/Path/To/File/File.php', $event->getPath()); + $this->assertTrue($event->isType(FSEvent::Renamed)); + $this->assertTrue($event->isType(FSEvent::OwnerModified)); } } \ No newline at end of file diff --git a/tests/HotReload/FSEventTest.php b/tests/HotReload/FSEventTest.php index 4df2d054..4fc19c4d 100644 --- a/tests/HotReload/FSEventTest.php +++ b/tests/HotReload/FSEventTest.php @@ -2,7 +2,7 @@ namespace SwooleTW\Http\Tests\HotReload; -use Illuminate\Support\Carbon; +use Carbon\Carbon; use SwooleTW\Http\HotReload\FSEvent; use SwooleTW\Http\Tests\TestCase; diff --git a/tests/HotReload/FSOutputTest.php b/tests/HotReload/FSOutputTest.php new file mode 100644 index 00000000..f89cb4bc --- /dev/null +++ b/tests/HotReload/FSOutputTest.php @@ -0,0 +1,24 @@ +assertEquals( + 'File: /Some/Path/To/File/File.php OwnerModified, Renamed at 2018.12.31 01:18:34', + FSOutput::format($event) + ); + } +} \ No newline at end of file diff --git a/tests/Server/ManagerTest.php b/tests/Server/ManagerTest.php index 48453096..0664c861 100644 --- a/tests/Server/ManagerTest.php +++ b/tests/Server/ManagerTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\Server; - use Illuminate\Container\Container; use Illuminate\Contracts\Config\Repository; use Illuminate\Contracts\Debug\ExceptionHandler; @@ -139,8 +138,8 @@ public function testOnWorkerStart() }); Config::shouldReceive('get') - ->with('swoole_websocket.middleware', []) - ->once(); + ->with('swoole_websocket.middleware', []) + ->once(); WebsocketFacade::shouldReceive('on')->times(3); $manager = $this->getWebsocketManager($container); @@ -198,23 +197,23 @@ public function testOnRequest() $container->singleton(Websocket::class, function () { $websocket = m::mock(Websocket::class); $websocket->shouldReceive('reset') - ->with(true) - ->once(); + ->with(true) + ->once(); return $websocket; }); $container->singleton(Sandbox::class, function () { $sandbox = m::mock(Sandbox::class); $sandbox->shouldReceive('setRequest') - ->with(m::type('Illuminate\Http\Request')) - ->once(); + ->with(m::type('Illuminate\Http\Request')) + ->once(); $sandbox->shouldReceive('enable') - ->once(); + ->once(); $sandbox->shouldReceive('run') - ->with(m::type('Illuminate\Http\Request')) - ->once(); + ->with(m::type('Illuminate\Http\Request')) + ->once(); $sandbox->shouldReceive('disable') - ->once(); + ->once(); return $sandbox; }); @@ -227,21 +226,21 @@ public function testOnRequest() $request = m::mock(Request::class); $request->shouldReceive('rawcontent') - ->once() - ->andReturn([]); + ->once() + ->andReturn([]); $response = m::mock(Response::class); $response->shouldReceive('header') - ->twice() - ->andReturnSelf(); + ->twice() + ->andReturnSelf(); $response->shouldReceive('status') - ->once() - ->andReturnSelf(); + ->once() + ->andReturnSelf(); $response->shouldReceive('write') - ->andReturnSelf(); + ->andReturnSelf(); $response->shouldReceive('end') - ->once() - ->andReturnSelf(); + ->once() + ->andReturnSelf(); $manager = $this->getWebsocketManager(); $manager->setApplication($container); @@ -258,7 +257,7 @@ public function testOnRequestException() $container->singleton(Sandbox::class, function () { $sandbox = m::mock(Sandbox::class); $sandbox->shouldReceive('disable') - ->once(); + ->once(); return $sandbox; }); @@ -268,7 +267,7 @@ public function testOnRequestException() $container->singleton(ExceptionHandler::class, function () { $handler = m::mock(ExceptionHandler::class); $handler->shouldReceive('render') - ->once(); + ->once(); return $handler; }); @@ -279,21 +278,21 @@ public function testOnRequestException() $request = m::mock(Request::class); $request->shouldReceive('rawcontent') - ->once() - ->andReturn([]); + ->once() + ->andReturn([]); $response = m::mock(Response::class); $response->shouldReceive('header') - ->twice() - ->andReturnSelf(); + ->twice() + ->andReturnSelf(); $response->shouldReceive('status') - ->once() - ->andReturnSelf(); + ->once() + ->andReturnSelf(); $response->shouldReceive('write') - ->andReturnSelf(); + ->andReturnSelf(); $response->shouldReceive('end') - ->once() - ->andReturnSelf(); + ->once() + ->andReturnSelf(); $manager = $this->getManager($container); $manager->setApplication($container); @@ -354,8 +353,8 @@ public function testLogServerError() $container->singleton(ExceptionHandler::class, function () use ($exception) { $handler = m::mock(ExceptionHandler::class); $handler->shouldReceive('report') - ->with($exception) - ->once(); + ->with($exception) + ->once(); return $handler; }); @@ -368,45 +367,45 @@ public function testOnOpen() { $request = m::mock(Request::class); $request->shouldReceive('rawcontent') - ->once() - ->andReturn([]); + ->once() + ->andReturn([]); $request->fd = 1; $container = $this->getContainer(); $container->singleton(Websocket::class, function () { $websocket = m::mock(Websocket::class); $websocket->shouldReceive('reset') - ->with(true) - ->once() - ->andReturnSelf(); + ->with(true) + ->once() + ->andReturnSelf(); $websocket->shouldReceive('setSender') - ->with(1) - ->once(); + ->with(1) + ->once(); $websocket->shouldReceive('eventExists') - ->with('connect') - ->once() - ->andReturn(true); + ->with('connect') + ->once() + ->andReturn(true); $websocket->shouldReceive('setContainer') - ->with(m::type(Container::class)) - ->once(); + ->with(m::type(Container::class)) + ->once(); $websocket->shouldReceive('call') - ->with('connect', m::type('Illuminate\Http\Request')) - ->once(); + ->with('connect', m::type('Illuminate\Http\Request')) + ->once(); return $websocket; }); $container->singleton(Sandbox::class, function () { $sandbox = m::mock(Sandbox::class); $sandbox->shouldReceive('setRequest') - ->with(m::type('Illuminate\Http\Request')) - ->once(); + ->with(m::type('Illuminate\Http\Request')) + ->once(); $sandbox->shouldReceive('enable') - ->once(); + ->once(); $sandbox->shouldReceive('disable') - ->once(); + ->once(); $sandbox->shouldReceive('getApplication') - ->once() - ->andReturn(m::mock(Container::class)); + ->once() + ->andReturn(m::mock(Container::class)); return $sandbox; }); @@ -415,8 +414,8 @@ public function testOnOpen() $handler = m::mock(HandlerContract::class); $handler->shouldReceive('onOpen') - ->with(1, m::type('Illuminate\Http\Request')) - ->andReturn(true); + ->with(1, m::type('Illuminate\Http\Request')) + ->andReturn(true); $manager = $this->getWebsocketManager(); $manager->setApplication($container); @@ -431,43 +430,43 @@ public function testOnMessage() $parser = m::mock(Parser::class); $parser->shouldReceive('execute') - ->with('server', $frame) - ->once() - ->andReturn(false); + ->with('server', $frame) + ->once() + ->andReturn(false); $parser->shouldReceive('decode') - ->with($frame) - ->once() - ->andReturn($payload = [ - 'event' => 'event', - 'data' => 'data', - ]); + ->with($frame) + ->once() + ->andReturn($payload = [ + 'event' => 'event', + 'data' => 'data', + ]); $container = $this->getContainer(); $container->singleton(Websocket::class, function () use ($payload) { $websocket = m::mock(Websocket::class); $websocket->shouldReceive('reset') - ->with(true) - ->once() - ->andReturnSelf(); + ->with(true) + ->once() + ->andReturnSelf(); $websocket->shouldReceive('setSender') - ->with(1) - ->once(); + ->with(1) + ->once(); $websocket->shouldReceive('eventExists') - ->with($payload['event']) - ->once() - ->andReturn(true); + ->with($payload['event']) + ->once() + ->andReturn(true); $websocket->shouldReceive('call') - ->with($payload['event'], $payload['data']) - ->once(); + ->with($payload['event'], $payload['data']) + ->once(); return $websocket; }); $container->singleton(Sandbox::class, function () { $sandbox = m::mock(Sandbox::class); $sandbox->shouldReceive('enable') - ->once(); + ->once(); $sandbox->shouldReceive('disable') - ->once(); + ->once(); return $sandbox; }); @@ -487,21 +486,21 @@ public function testOnClose() $app->singleton(Websocket::class, function () use ($fd) { $websocket = m::mock(Websocket::class); $websocket->shouldReceive('reset') - ->with(true) - ->once() - ->andReturnSelf(); + ->with(true) + ->once() + ->andReturnSelf(); $websocket->shouldReceive('setSender') - ->with($fd) - ->once(); + ->with($fd) + ->once(); $websocket->shouldReceive('eventExists') - ->with('disconnect') - ->once() - ->andReturn(true); + ->with('disconnect') + ->once() + ->andReturn(true); $websocket->shouldReceive('call') - ->with('disconnect') - ->once(); + ->with('disconnect') + ->once(); $websocket->shouldReceive('leave') - ->once(); + ->once(); return $websocket; }); @@ -516,11 +515,11 @@ public function testOnClose() $server->taskworker = false; $server->master_pid = -1; $server->shouldReceive('connection_info') - ->with($fd) - ->once() - ->andReturn([ - 'websocket_status' => true, - ]); + ->with($fd) + ->once() + ->andReturn([ + 'websocket_status' => true, + ]); return $server; }); @@ -566,16 +565,16 @@ public function testPushMessage() $parser = m::mock(Parser::class); $parser->shouldReceive('encode') - ->with($data['event'], $data['message']) - ->once() - ->andReturn(false); + ->with($data['event'], $data['message']) + ->once() + ->andReturn(false); $server = m::mock('server'); $server->shouldReceive('exist') - ->times(count($data['fds'])) - ->andReturn(true); + ->times(count($data['fds'])) + ->andReturn(true); $server->shouldReceive('push') - ->times(count($data['fds'])); + ->times(count($data['fds'])); $manager = $this->getWebsocketManager(); $manager->setPayloadParser($parser); @@ -631,11 +630,11 @@ protected function getConfig($websocket = false) }; $config->shouldReceive('get') - ->with(m::type('string'), m::any()) - ->andReturnUsing($callback); + ->with(m::type('string'), m::any()) + ->andReturnUsing($callback); $config->shouldReceive('get') - ->with(m::type('string')) - ->andReturnUsing($callback); + ->with(m::type('string')) + ->andReturnUsing($callback); return $config; } @@ -643,9 +642,9 @@ protected function getConfig($websocket = false) protected function getEvent($name, $default = true) { $event = m::mock('event') - ->shouldReceive('fire') - ->with($name, m::any()) - ->once(); + ->shouldReceive('fire') + ->with($name, m::any()) + ->once(); $event = $default ? $event->with($name, m::any()) : $event->with($name); diff --git a/tests/Server/ResettersTest.php b/tests/Server/ResettersTest.php index 72bbffbd..e5ef0bcb 100644 --- a/tests/Server/ResettersTest.php +++ b/tests/Server/ResettersTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\Server; - use Illuminate\Container\Container; use Illuminate\Contracts\Config\Repository; use Illuminate\Contracts\Http\Kernel; @@ -30,8 +29,8 @@ public function testBindRequest() $sandbox = m::mock(Sandbox::class); $sandbox->shouldReceive('getRequest') - ->once() - ->andReturn($request); + ->once() + ->andReturn($request); $container = new Container; @@ -45,9 +44,9 @@ public function testClearInstance() { $sandbox = m::mock(Sandbox::class); $sandbox->shouldReceive('getConfig->get') - ->with('swoole_http.instances', []) - ->once() - ->andReturn(['foo']); + ->with('swoole_http.instances', []) + ->once() + ->andReturn(['foo']); $container = new Container; $container->instance('foo', m::mock('foo')); @@ -62,8 +61,8 @@ public function testRebindKernelContainer() { $sandbox = m::mock(Sandbox::class); $sandbox->shouldReceive('isLaravel') - ->once() - ->andReturn(true); + ->once() + ->andReturn(true); $kernel = m::mock(Kernel::class); @@ -82,11 +81,11 @@ public function testRebindLaravelRouterContainer() $sandbox = m::mock(Sandbox::class); $sandbox->shouldReceive('isLaravel') - ->once() - ->andReturn(true); + ->once() + ->andReturn(true); $sandbox->shouldReceive('getRequest') - ->once() - ->andReturn($request); + ->once() + ->andReturn($request); $router = m::mock('router'); @@ -96,14 +95,14 @@ public function testRebindLaravelRouterContainer() $route = m::mock('route'); $route->controller = 'controller'; $route->shouldReceive('setContainer') - ->once() - ->with($container); + ->once() + ->with($container); $routes = m::mock('routes'); $routes->shouldReceive('match') - ->once() - ->with($request) - ->andReturn($route); + ->once() + ->with($request) + ->andReturn($route); $router->routes = $routes; @@ -117,19 +116,19 @@ public function testRebindLumenRouterContainer() { $sandbox = m::mock(Sandbox::class); $sandbox->shouldReceive('isLaravel') - ->once() - ->andReturn(false); + ->once() + ->andReturn(false); $router = m::mock('router'); $container = m::mock(Container::class); $container->shouldReceive('offsetSet') - ->with('router', $router) - ->once() - ->andReturnSelf(); + ->with('router', $router) + ->once() + ->andReturnSelf(); $container->shouldReceive('offsetGet') - ->with('router') - ->andReturn($router); + ->with('router') + ->andReturn($router); $container->router = $router; $this->mockMethod('property_exists', function () { @@ -162,8 +161,8 @@ public function testResetConfig() $config = m::mock(Repository::class); $sandbox = m::mock(Sandbox::class); $sandbox->shouldReceive('getConfig') - ->once() - ->andReturn($config); + ->once() + ->andReturn($config); $container = new Container; $resetter = new ResetConfig; @@ -176,11 +175,11 @@ public function testResetCookie() { $cookies = m::mock('cookies'); $cookies->shouldReceive('getQueuedCookies') - ->once() - ->andReturn(['foo']); + ->once() + ->andReturn(['foo']); $cookies->shouldReceive('unqueue') - ->once() - ->with('foo'); + ->once() + ->with('foo'); $sandbox = m::mock(Sandbox::class); @@ -195,9 +194,9 @@ public function testResetSession() { $session = m::mock('session'); $session->shouldReceive('flush') - ->once(); + ->once(); $session->shouldReceive('regenerate') - ->once(); + ->once(); $sandbox = m::mock(Sandbox::class); @@ -212,14 +211,14 @@ public function testResetProviders() { $provider = m::mock(TestProvider::class); $provider->shouldReceive('register') - ->once(); + ->once(); $provider->shouldReceive('boot') - ->once(); + ->once(); $sandbox = m::mock(Sandbox::class); $sandbox->shouldReceive('getProviders') - ->once() - ->andReturn([$provider]); + ->once() + ->andReturn([$provider]); $this->mockMethod('method_exists', function () { return true; diff --git a/tests/Server/SandboxTest.php b/tests/Server/SandboxTest.php index 0a110cfd..876d3bc9 100644 --- a/tests/Server/SandboxTest.php +++ b/tests/Server/SandboxTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\Server; - use Illuminate\Config\Repository; use Illuminate\Container\Container; use Illuminate\Contracts\Container\Container as ContainerContract; @@ -53,23 +52,23 @@ public function testInitialize() $config = m::mock(Repository::class); $config->shouldReceive('get') - ->with('swoole_http.providers', []) - ->once() - ->andReturn([$providerName]); + ->with('swoole_http.providers', []) + ->once() + ->andReturn([$providerName]); $config->shouldReceive('get') - ->with('swoole_http.resetters', []) - ->once() - ->andReturn([$resetterName]); + ->with('swoole_http.resetters', []) + ->once() + ->andReturn([$resetterName]); $container = m::mock(Container::class); $container->shouldReceive('make') - ->with(\Illuminate\Contracts\Config\Repository::class) - ->once() - ->andReturn($config); + ->with(\Illuminate\Contracts\Config\Repository::class) + ->once() + ->andReturn($config); $container->shouldReceive('make') - ->with($resetterName) - ->once() - ->andReturn($resetter); + ->with($resetterName) + ->once() + ->andReturn($resetter); $sandbox = new Sandbox; $sandbox->setBaseApp($container); @@ -101,9 +100,9 @@ public function testGetCachedSnapshot() $container = m::mock(Container::class); $snapshot = m::mock(Container::class); $snapshot->shouldReceive('offsetGet') - ->with('foo') - ->once() - ->andReturn($result = 'bar'); + ->with('foo') + ->once() + ->andReturn($result = 'bar'); $sandbox = new Sandbox; $sandbox->setBaseApp($container); @@ -154,12 +153,12 @@ protected function getContainer() { $config = m::mock(Illuminate\Config\Repository::class); $config->shouldReceive('get') - ->andReturn([]); + ->andReturn([]); $container = m::mock(Container::class); $container->shouldReceive('offsetGet') - ->andReturn((object)[]); + ->andReturn((object) []); $container->shouldReceive('make') - ->andReturn($config); + ->andReturn($config); return $container; } diff --git a/tests/SocketIO/PacketTest.php b/tests/SocketIO/PacketTest.php index e2b7b20d..b46b1013 100644 --- a/tests/SocketIO/PacketTest.php +++ b/tests/SocketIO/PacketTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\SocketIO; - use SwooleTW\Http\Tests\TestCase; use SwooleTW\Http\Websocket\SocketIO\Packet; diff --git a/tests/SocketIO/ParserTest.php b/tests/SocketIO/ParserTest.php index 346a829c..9b952a99 100644 --- a/tests/SocketIO/ParserTest.php +++ b/tests/SocketIO/ParserTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\SocketIO; - use Illuminate\Support\Facades\App; use Mockery as m; use Swoole\Websocket\Frame; @@ -25,7 +24,7 @@ public function testEncode() $data = ['message' => 'test']; $this->assertSame('42["foo",{"message":"test"}]', $parser->encode($event, $data)); - $data = (object)['message' => 'test']; + $data = (object) ['message' => 'test']; $this->assertSame('42["foo",{"message":"test"}]', $parser->encode($event, $data)); } diff --git a/tests/SocketIO/SocketIOControllerTest.php b/tests/SocketIO/SocketIOControllerTest.php index d9a9f78d..e445e3db 100644 --- a/tests/SocketIO/SocketIOControllerTest.php +++ b/tests/SocketIO/SocketIOControllerTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\SocketIO; - use Illuminate\Http\Request; use Illuminate\Support\Facades\Config; use Mockery as m; @@ -15,18 +14,18 @@ public function testUnknownTransport() { $request = m::mock(Request::class); $request->shouldReceive('input') - ->with('transport') - ->once() - ->andReturn('foo'); + ->with('transport') + ->once() + ->andReturn('foo'); $this->mockMethod('response', function () { $response = m::mock('response'); $response->shouldReceive('json') - ->once() - ->with([ - 'code' => 0, - 'message' => 'Transport unknown', - ], 400); + ->once() + ->with([ + 'code' => 0, + 'message' => 'Transport unknown', + ], 400); return $response; }); @@ -39,13 +38,13 @@ public function testHasSid() { $request = m::mock(Request::class); $request->shouldReceive('input') - ->with('transport') - ->once() - ->andReturn('websocket'); + ->with('transport') + ->once() + ->andReturn('websocket'); $request->shouldReceive('has') - ->with('sid') - ->once() - ->andReturn(true); + ->with('sid') + ->once() + ->andReturn(true); $controller = new SocketIOController; $result = $controller->upgrade($request); @@ -57,13 +56,13 @@ public function testUpgradePayload() { $request = m::mock(Request::class); $request->shouldReceive('input') - ->with('transport') - ->once() - ->andReturn('websocket'); + ->with('transport') + ->once() + ->andReturn('websocket'); $request->shouldReceive('has') - ->with('sid') - ->once() - ->andReturn(false); + ->with('sid') + ->once() + ->andReturn(false); $base64Encode = false; $this->mockMethod('base64_encode', function () use (&$base64Encode) { @@ -73,13 +72,13 @@ public function testUpgradePayload() }); Config::shouldReceive('get') - ->with('swoole_websocket.ping_interval') - ->once() - ->andReturn(1); + ->with('swoole_websocket.ping_interval') + ->once() + ->andReturn(1); Config::shouldReceive('get') - ->with('swoole_websocket.ping_timeout') - ->once() - ->andReturn(1); + ->with('swoole_websocket.ping_timeout') + ->once() + ->andReturn(1); $expectedPayload = json_encode([ 'sid' => 'payload', @@ -101,11 +100,11 @@ public function testReject() $this->mockMethod('response', function () { $response = m::mock('response'); $response->shouldReceive('json') - ->once() - ->with([ - 'code' => 3, - 'message' => 'Bad request', - ], 400); + ->once() + ->with([ + 'code' => 3, + 'message' => 'Bad request', + ], 400); return $response; }); diff --git a/tests/SocketIO/WebsocketHandlerTest.php b/tests/SocketIO/WebsocketHandlerTest.php index c83bed2c..6db1e612 100644 --- a/tests/SocketIO/WebsocketHandlerTest.php +++ b/tests/SocketIO/WebsocketHandlerTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\SocketIO; - use Illuminate\Http\Request; use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\Config; @@ -19,16 +18,16 @@ public function testOnOpen() $fd = 1; $request = m::mock(Request::class); $request->shouldReceive('input') - ->with('sid') - ->once() - ->andReturn(false); + ->with('sid') + ->once() + ->andReturn(false); Config::shouldReceive('get') - ->with('swoole_websocket.ping_interval') - ->once(); + ->with('swoole_websocket.ping_interval') + ->once(); Config::shouldReceive('get') - ->with('swoole_websocket.ping_timeout') - ->once(); + ->with('swoole_websocket.ping_timeout') + ->once(); $jsonEncode = false; $this->mockMethod('json_encode', function () use (&$jsonEncode) { @@ -38,15 +37,15 @@ public function testOnOpen() }, 'SwooleTW\Http\Websocket\SocketIO'); App::shouldReceive('make') - ->with(Server::class) - ->twice() - ->andReturnSelf(); + ->with(Server::class) + ->twice() + ->andReturnSelf(); App::shouldReceive('push') - ->with($fd, '0{foo: "bar"}') - ->once(); + ->with($fd, '0{foo: "bar"}') + ->once(); App::shouldReceive('push') - ->with($fd, '40') - ->once(); + ->with($fd, '40') + ->once(); $handler = new WebsocketHandler; $this->assertTrue($handler->onOpen($fd, $request)); @@ -58,9 +57,9 @@ public function testOnOpenWithFalseReturn() $fd = 1; $request = m::mock(Request::class); $request->shouldReceive('input') - ->with('sid') - ->once() - ->andReturn(true); + ->with('sid') + ->once() + ->andReturn(true); $handler = new WebsocketHandler; $this->assertFalse($handler->onOpen($fd, $request)); diff --git a/tests/Table/TableTest.php b/tests/Table/TableTest.php index 7e35a6e4..fa32dbed 100644 --- a/tests/Table/TableTest.php +++ b/tests/Table/TableTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\Table; - use Mockery as m; use Swoole\Table; use SwooleTW\Http\Table\SwooleTable; diff --git a/tests/Task/FakeJob.php b/tests/Task/FakeJob.php index 37f953b9..272b658b 100644 --- a/tests/Task/FakeJob.php +++ b/tests/Task/FakeJob.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\Task; - use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Queue\InteractsWithQueue; diff --git a/tests/Task/QueueFactoryTest.php b/tests/Task/QueueFactoryTest.php index 4afc0e51..0f27937e 100644 --- a/tests/Task/QueueFactoryTest.php +++ b/tests/Task/QueueFactoryTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\Task; - use Illuminate\Support\Str; use Mockery as m; use SwooleTW\Http\Helpers\FW; diff --git a/tests/Task/SwooleJobTest.php b/tests/Task/SwooleJobTest.php index 98fc5c23..2f2ffaca 100644 --- a/tests/Task/SwooleJobTest.php +++ b/tests/Task/SwooleJobTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\Task; - use Illuminate\Container\Container; use Mockery as m; use SwooleTW\Http\Task\SwooleTaskJob; diff --git a/tests/Task/SwooleQueueTest.php b/tests/Task/SwooleQueueTest.php index bb3fcf23..cbff7344 100644 --- a/tests/Task/SwooleQueueTest.php +++ b/tests/Task/SwooleQueueTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\Task; - use Mockery as m; use SwooleTW\Http\Helpers\FW; use SwooleTW\Http\Task\QueueFactory; diff --git a/tests/TestCase.php b/tests/TestCase.php index 0965d984..1e666707 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests; - use Illuminate\Support\Facades\Facade; use Mockery as m; use phpmock\Mock; @@ -27,10 +26,10 @@ public function tearDown() protected function mockMethod($name, \Closure $function, $namespace = null) { - $builder = new MockBuilder(); + $builder = new MockBuilder; $builder->setNamespace($namespace) - ->setName($name) - ->setFunction($function); + ->setName($name) + ->setFunction($function); $mock = $builder->build(); $mock->enable(); diff --git a/tests/Transformers/RequestTest.php b/tests/Transformers/RequestTest.php index d89bf7db..2eecd190 100644 --- a/tests/Transformers/RequestTest.php +++ b/tests/Transformers/RequestTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\Transformers; - use Illuminate\Http\Request as IlluminateRequest; use Mockery as m; use Swoole\Http\Request as SwooleRequest; @@ -48,14 +47,14 @@ public function testHandleStatic() $response = m::mock('response'); $response->shouldReceive('status') - ->with(200) - ->once(); + ->with(200) + ->once(); $response->shouldReceive('header') - ->with('Content-Type', 'foo') - ->once(); + ->with('Content-Type', 'foo') + ->once(); $response->shouldReceive('sendfile') - ->with('/foo.bar') - ->once(); + ->with('/foo.bar') + ->once(); Request::handleStatic(new SwooleRequestStub, $response, '/'); diff --git a/tests/Transformers/ResponseTest.php b/tests/Transformers/ResponseTest.php index 3a2c268d..41df5999 100644 --- a/tests/Transformers/ResponseTest.php +++ b/tests/Transformers/ResponseTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\Transformers; - use Illuminate\Http\Response as IlluminateResponse; use Swoole\Http\Response as SwooleResponse; use SwooleTW\Http\Tests\TestCase; diff --git a/tests/Websocket/Middleware/AuthenticateTest.php b/tests/Websocket/Middleware/AuthenticateTest.php index 7f24acd1..fcd5b4f9 100644 --- a/tests/Websocket/Middleware/AuthenticateTest.php +++ b/tests/Websocket/Middleware/AuthenticateTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\Websocket\Middleware; - use Illuminate\Contracts\Auth\Factory as Auth; use Illuminate\Http\Request; use Mockery as m; @@ -15,12 +14,12 @@ public function testAuthenticate() { $auth = m::mock(Auth::class); $auth->shouldReceive('authenticate') - ->once() - ->andReturn('user'); + ->once() + ->andReturn('user'); $request = m::mock(Request::class); $request->shouldReceive('setUserResolver') - ->once(); + ->once(); $middleware = new Authenticate($auth); $middleware->handle($request, function ($next) { diff --git a/tests/Websocket/Middleware/DecrpytCookiesTest.php b/tests/Websocket/Middleware/DecrpytCookiesTest.php index 586f171e..8c0347b0 100644 --- a/tests/Websocket/Middleware/DecrpytCookiesTest.php +++ b/tests/Websocket/Middleware/DecrpytCookiesTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\Websocket\Middleware; - use Illuminate\Contracts\Encryption\Encrypter as EncrypterContract; use Illuminate\Http\Request; use Mockery as m; @@ -34,11 +33,11 @@ public function testDecrypt() $encrypter = m::mock(EncrypterContract::class); $encrypter->shouldReceive('decrypt') - ->once() - ->with('sasaya', false); + ->once() + ->with('sasaya', false); $encrypter->shouldReceive('decrypt') - ->once() - ->with('ccc', false); + ->once() + ->with('ccc', false); $middleware = $this->getMiddleware($encrypter); $middleware->disableFor('foo'); diff --git a/tests/Websocket/Middleware/StartSessionTest.php b/tests/Websocket/Middleware/StartSessionTest.php index b9d75c64..0ab4c8e4 100644 --- a/tests/Websocket/Middleware/StartSessionTest.php +++ b/tests/Websocket/Middleware/StartSessionTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\Websocket\Middleware; - use SwooleTW\Http\Tests\TestCase; class StartSessionTest extends TestCase diff --git a/tests/Websocket/RedisRoomTest.php b/tests/Websocket/RedisRoomTest.php index ce2b3634..eeda14c2 100644 --- a/tests/Websocket/RedisRoomTest.php +++ b/tests/Websocket/RedisRoomTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\Websocket; - use Mockery as m; use Predis\Client as RedisClient; use SwooleTW\Http\Tests\TestCase; @@ -14,11 +13,11 @@ public function testPrepare() { $redis = $this->getRedis(); $redis->shouldReceive('keys') - ->once() - ->andReturn($keys = ['foo', 'bar']); + ->once() + ->andReturn($keys = ['foo', 'bar']); $redis->shouldReceive('del') - ->with($keys) - ->once(); + ->with($keys) + ->once(); $redisRoom = new RedisRoom([]); $redisRoom->prepare($redis); @@ -39,7 +38,7 @@ public function testAddValue() { $redis = $this->getRedis(); $redis->shouldReceive('pipeline') - ->once(); + ->once(); $redisRoom = $this->getRedisRoom($redis); $redisRoom->addValue(1, ['foo', 'bar'], 'fds'); @@ -49,7 +48,7 @@ public function testAddAll() { $redis = $this->getRedis(); $redis->shouldReceive('pipeline') - ->times(3); + ->times(3); $redisRoom = $this->getRedisRoom($redis); $redisRoom->add(1, ['foo', 'bar']); @@ -59,7 +58,7 @@ public function testAdd() { $redis = $this->getRedis(); $redis->shouldReceive('pipeline') - ->twice(); + ->twice(); $redisRoom = $this->getRedisRoom($redis); $redisRoom->add(1, 'foo'); @@ -69,7 +68,7 @@ public function testDeleteAll() { $redis = $this->getRedis(); $redis->shouldReceive('pipeline') - ->times(3); + ->times(3); $redisRoom = $this->getRedisRoom($redis); $redisRoom->delete(1, ['foo', 'bar']); @@ -79,7 +78,7 @@ public function testDelete() { $redis = $this->getRedis(); $redis->shouldReceive('pipeline') - ->twice(); + ->twice(); $redisRoom = $this->getRedisRoom($redis); $redisRoom->delete(1, 'foo'); @@ -89,8 +88,8 @@ public function testGetRooms() { $redis = $this->getRedis(); $redis->shouldReceive('smembers') - ->with('swoole:fds:1') - ->once(); + ->with('swoole:fds:1') + ->once(); $redisRoom = $this->getRedisRoom($redis); $redisRoom->getRooms(1); @@ -100,8 +99,8 @@ public function testGetClients() { $redis = $this->getRedis(); $redis->shouldReceive('smembers') - ->with('swoole:rooms:foo') - ->once(); + ->with('swoole:rooms:foo') + ->once(); $redisRoom = $this->getRedisRoom($redis); $redisRoom->getClients('foo'); diff --git a/tests/Websocket/SimpleParserTest.php b/tests/Websocket/SimpleParserTest.php index 214b3a26..f55f28e1 100644 --- a/tests/Websocket/SimpleParserTest.php +++ b/tests/Websocket/SimpleParserTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\Websocket; - use Mockery as m; use Swoole\Websocket\Frame; use SwooleTW\Http\Tests\TestCase; diff --git a/tests/Websocket/TableRoomTest.php b/tests/Websocket/TableRoomTest.php index a34fdaa1..26a6813b 100644 --- a/tests/Websocket/TableRoomTest.php +++ b/tests/Websocket/TableRoomTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\Websocket; - use Swoole\Table; use SwooleTW\Http\Tests\TestCase; use SwooleTW\Http\Websocket\Rooms\RoomContract; diff --git a/tests/Websocket/WebsocketTest.php b/tests/Websocket/WebsocketTest.php index 3541bfb6..1bb95688 100644 --- a/tests/Websocket/WebsocketTest.php +++ b/tests/Websocket/WebsocketTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\Websocket; - use Illuminate\Container\Container; use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Http\Request; @@ -46,60 +45,60 @@ public function testJoin() { $room = m::mock(RoomContract::class); $room->shouldReceive('add') - ->with($sender = 1, $name = ['room']) - ->once(); + ->with($sender = 1, $name = ['room']) + ->once(); $websocket = $this->getWebsocket($room) - ->setSender($sender) - ->join($name); + ->setSender($sender) + ->join($name); } public function testInAlias() { $room = m::mock(RoomContract::class); $room->shouldReceive('add') - ->with($sender = 1, $name = ['room']) - ->once(); + ->with($sender = 1, $name = ['room']) + ->once(); $websocket = $this->getWebsocket($room) - ->setSender($sender) - ->in($name); + ->setSender($sender) + ->in($name); } public function testJoinAll() { $room = m::mock(RoomContract::class); $room->shouldReceive('add') - ->with($sender = 1, $names = ['room1', 'room2']) - ->once(); + ->with($sender = 1, $names = ['room1', 'room2']) + ->once(); $websocket = $this->getWebsocket($room) - ->setSender($sender) - ->join($names); + ->setSender($sender) + ->join($names); } public function testLeave() { $room = m::mock(RoomContract::class); $room->shouldReceive('delete') - ->with($sender = 1, $name = ['room']) - ->once(); + ->with($sender = 1, $name = ['room']) + ->once(); $websocket = $this->getWebsocket($room) - ->setSender($sender) - ->leave($name); + ->setSender($sender) + ->leave($name); } public function testLeaveAll() { $room = m::mock(RoomContract::class); $room->shouldReceive('delete') - ->with($sender = 1, $names = ['room1', 'room2']) - ->once(); + ->with($sender = 1, $names = ['room1', 'room2']) + ->once(); $websocket = $this->getWebsocket($room) - ->setSender($sender) - ->leave($names); + ->setSender($sender) + ->leave($names); } public function testCallbacks() @@ -121,50 +120,50 @@ public function testLoginUsing() { $user = m::mock(AuthenticatableContract::class); $user->shouldReceive('getAuthIdentifier') - ->once() - ->andReturn($id = 1); + ->once() + ->andReturn($id = 1); $room = m::mock(RoomContract::class); $room->shouldReceive('add') - ->with($sender = 1, ['uid_1']) - ->once(); + ->with($sender = 1, ['uid_1']) + ->once(); $websocket = $this->getWebsocket($room) - ->setSender($sender) - ->loginUsing($user); + ->setSender($sender) + ->loginUsing($user); } public function testLoginUsingId() { $room = m::mock(RoomContract::class); $room->shouldReceive('add') - ->with($sender = 1, ['uid_1']) - ->once(); + ->with($sender = 1, ['uid_1']) + ->once(); $websocket = $this->getWebsocket($room) - ->setSender($sender) - ->loginUsingId(1); + ->setSender($sender) + ->loginUsingId(1); } public function testToUserId() { $room = m::mock(RoomContract::class); $room->shouldReceive('getClients') - ->with('uid_1') - ->once() - ->andReturn([$uid = 1]); + ->with('uid_1') + ->once() + ->andReturn([$uid = 1]); $websocket = $this->getWebsocket($room)->toUserId($uid); $this->assertTrue(in_array($uid, $websocket->getTo())); $room->shouldReceive('getClients') - ->with('uid_2') - ->once() - ->andReturn([2]); + ->with('uid_2') + ->once() + ->andReturn([2]); $room->shouldReceive('getClients') - ->with('uid_3') - ->once() - ->andReturn([3]); + ->with('uid_3') + ->once() + ->andReturn([3]); $websocket->toUserId([2, 3]); $this->assertTrue(in_array(2, $websocket->getTo())); @@ -175,35 +174,35 @@ public function testToUser() { $user = m::mock(AuthenticatableContract::class); $user->shouldReceive('getAuthIdentifier') - ->once() - ->andReturn($uid = 1); + ->once() + ->andReturn($uid = 1); $room = m::mock(RoomContract::class); $room->shouldReceive('getClients') - ->with('uid_1') - ->once() - ->andReturn([$uid]); + ->with('uid_1') + ->once() + ->andReturn([$uid]); $websocket = $this->getWebsocket($room)->toUser($user); $this->assertTrue(in_array($uid, $websocket->getTo())); $room->shouldReceive('getClients') - ->with('uid_2') - ->once() - ->andReturn([2]); + ->with('uid_2') + ->once() + ->andReturn([2]); $room->shouldReceive('getClients') - ->with('uid_3') - ->once() - ->andReturn([3]); + ->with('uid_3') + ->once() + ->andReturn([3]); $userA = m::mock(AuthenticatableContract::class); $userA->shouldReceive('getAuthIdentifier') - ->once() - ->andReturn(2); + ->once() + ->andReturn(2); $userB = m::mock(AuthenticatableContract::class); $userB->shouldReceive('getAuthIdentifier') - ->once() - ->andReturn(3); + ->once() + ->andReturn(3); $websocket->toUser($users = [$userA, $userB]); $this->assertTrue(in_array(2, $websocket->getTo())); @@ -214,9 +213,9 @@ public function testGetUserId() { $room = m::mock(RoomContract::class); $room->shouldReceive('getRooms') - ->with($sender = 1) - ->once() - ->andReturn(['uid_1']); + ->with($sender = 1) + ->once() + ->andReturn(['uid_1']); $websocket = $this->getWebsocket($room)->setSender($sender); $this->assertEquals($sender, $websocket->getUserId()); @@ -226,12 +225,12 @@ public function testLogout() { $room = m::mock(RoomContract::class); $room->shouldReceive('getRooms') - ->with($sender = 1) - ->once() - ->andReturn(['uid_1']); + ->with($sender = 1) + ->once() + ->andReturn(['uid_1']); $room->shouldReceive('delete') - ->with($sender, $name = ['uid_1']) - ->once(); + ->with($sender, $name = ['uid_1']) + ->once(); $websocket = $this->getWebsocket($room)->setSender($sender); $websocket->logout(); @@ -241,9 +240,9 @@ public function testIsUserIdOnline() { $room = m::mock(RoomContract::class); $room->shouldReceive('getClients') - ->with('uid_1') - ->once() - ->andReturn([1]); + ->with('uid_1') + ->once() + ->andReturn([1]); $websocket = $this->getWebsocket($room); $this->assertTrue($websocket->isUserIdOnline(1)); @@ -253,8 +252,8 @@ public function testReset() { $websocket = $this->getWebsocket(); $websocket->setSender(1) - ->broadcast() - ->to('foo'); + ->broadcast() + ->to('foo'); $websocket->reset(true); @@ -266,23 +265,23 @@ public function testReset() public function testPipeline() { App::shouldReceive('call') - ->once() - ->andReturnSelf(); + ->once() + ->andReturnSelf(); $request = m::mock(Request::class); $middlewares = ['foo', 'bar']; $pipeline = m::mock(Pipeline::class); $pipeline->shouldReceive('send') - ->with($request) - ->once() - ->andReturnSelf(); + ->with($request) + ->once() + ->andReturnSelf(); $pipeline->shouldReceive('through') - ->with($middlewares) - ->once() - ->andReturnSelf(); + ->with($middlewares) + ->once() + ->andReturnSelf(); $pipeline->shouldReceive('then') - ->once() - ->andReturn($request); + ->once() + ->andReturn($request); $websocket = $this->getWebsocket(null, $pipeline); $websocket->middleware($middlewares); @@ -323,34 +322,34 @@ public function testEmit() $broadcast = true; $room = m::mock(RoomContract::class); $room->shouldReceive('getClients') - ->with(m::type('string')) - ->times(3) - ->andReturn([3, 4, 5]); + ->with(m::type('string')) + ->times(3) + ->andReturn([3, 4, 5]); App::shouldReceive('make') - ->with(Server::class) - ->once() - ->andReturnSelf(); + ->with(Server::class) + ->once() + ->andReturnSelf(); App::shouldReceive('task') - ->with([ - 'action' => 'push', - 'data' => [ - 'sender' => $sender, - 'fds' => [1, 2, 3, 4, 5], - 'broadcast' => $broadcast, - 'assigned' => true, - 'event' => $event = 'event', - 'message' => $data = 'data', - ], - ]) - ->once(); + ->with([ + 'action' => 'push', + 'data' => [ + 'sender' => $sender, + 'fds' => [1, 2, 3, 4, 5], + 'broadcast' => $broadcast, + 'assigned' => true, + 'event' => $event = 'event', + 'message' => $data = 'data', + ], + ]) + ->once(); $websocket = $this->getWebsocket($room); $websocket->setSender($sender) - ->to($to) - ->broadcast() - ->emit($event, $data); + ->to($to) + ->broadcast() + ->emit($event, $data); $this->assertSame([], $websocket->getTo()); $this->assertFalse($websocket->getIsBroadcast()); @@ -361,13 +360,13 @@ public function testClose() $fd = 1; App::shouldReceive('make') - ->with(Server::class) - ->once() - ->andReturnSelf(); + ->with(Server::class) + ->once() + ->andReturnSelf(); App::shouldReceive('close') - ->with($fd) - ->once(); + ->with($fd) + ->once(); $websocket = $this->getWebsocket(); $websocket->close($fd); @@ -379,8 +378,8 @@ protected function getWebsocket(RoomContract $room = null, $pipeline = null) $pipeline = $pipeline ?: m::mock(Pipeline::class); Config::shouldReceive('get') - ->once() - ->andReturn([]); + ->once() + ->andReturn([]); return new Websocket($room, $pipeline); } diff --git a/tests/fixtures/bootstrap/app.php b/tests/fixtures/bootstrap/app.php index 4ab5ca49..ed346bb1 100644 --- a/tests/fixtures/bootstrap/app.php +++ b/tests/fixtures/bootstrap/app.php @@ -1,6 +1,5 @@ Date: Mon, 31 Dec 2018 16:58:17 +0200 Subject: [PATCH 026/161] Fix for array_sort. --- src/Coroutine/Connectors/MySqlConnector.php | 1 + src/HotReload/FSEventParser.php | 2 +- tests/HotReload/FSEventTest.php | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Coroutine/Connectors/MySqlConnector.php b/src/Coroutine/Connectors/MySqlConnector.php index 2efa720a..7082d761 100644 --- a/src/Coroutine/Connectors/MySqlConnector.php +++ b/src/Coroutine/Connectors/MySqlConnector.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http\Coroutine\Connectors; + use Illuminate\Database\Connectors\MySqlConnector as BaseConnector; use Illuminate\Support\Str; use SwooleTW\Http\Coroutine\PDO as SwoolePDO; diff --git a/src/HotReload/FSEventParser.php b/src/HotReload/FSEventParser.php index d526030d..676cae6c 100644 --- a/src/HotReload/FSEventParser.php +++ b/src/HotReload/FSEventParser.php @@ -26,7 +26,7 @@ public static function toEvent(string $event): ?FSEvent $date = Carbon::parse($matches[static::DATE]); $path = $matches[static::PATH]; $events = explode(' ', $matches[static::EVENTS]); - $events = array_sort(array_intersect(FSEvent::getPossibleTypes(), $events)); + $events = array_sort(array_intersect(FSEvent::getPossibleTypes(), $events), SORT_ASC); return new FSEvent($date, $path, $events); } diff --git a/tests/HotReload/FSEventTest.php b/tests/HotReload/FSEventTest.php index 4fc19c4d..7ecea71f 100644 --- a/tests/HotReload/FSEventTest.php +++ b/tests/HotReload/FSEventTest.php @@ -16,7 +16,7 @@ public function testObjectIsCorrect() $date = Carbon::parse('Mon Dec 31 01:18:34 2018'); $path = '/Some/Path/To/File/File.php'; $events = explode(' ', 'Renamed OwnerModified IsFile'); - $events = array_sort(array_intersect(FSEvent::getPossibleTypes(), $events)); + $events = array_sort(array_intersect(FSEvent::getPossibleTypes(), $events), SORT_ASC); $event = new FSEvent($date, $path, $events); $this->assertTrue(array_diff($event->getTypes(), [FSEvent::Renamed, FSEvent::OwnerModified]) === []); From 731fe952136c5c425e17e1915a382f81fde0c65f Mon Sep 17 00:00:00 2001 From: Fractal Zombie Date: Mon, 31 Dec 2018 17:04:00 +0200 Subject: [PATCH 027/161] Fix for array_sort. --- src/HotReload/FSEventParser.php | 3 ++- tests/HotReload/FSEventTest.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/HotReload/FSEventParser.php b/src/HotReload/FSEventParser.php index 676cae6c..927e1ff3 100644 --- a/src/HotReload/FSEventParser.php +++ b/src/HotReload/FSEventParser.php @@ -26,7 +26,8 @@ public static function toEvent(string $event): ?FSEvent $date = Carbon::parse($matches[static::DATE]); $path = $matches[static::PATH]; $events = explode(' ', $matches[static::EVENTS]); - $events = array_sort(array_intersect(FSEvent::getPossibleTypes(), $events), SORT_ASC); + $events = array_intersect(FSEvent::getPossibleTypes(), $events); + asort($events, SORT_ASC); return new FSEvent($date, $path, $events); } diff --git a/tests/HotReload/FSEventTest.php b/tests/HotReload/FSEventTest.php index 7ecea71f..7a3ef0a4 100644 --- a/tests/HotReload/FSEventTest.php +++ b/tests/HotReload/FSEventTest.php @@ -16,7 +16,8 @@ public function testObjectIsCorrect() $date = Carbon::parse('Mon Dec 31 01:18:34 2018'); $path = '/Some/Path/To/File/File.php'; $events = explode(' ', 'Renamed OwnerModified IsFile'); - $events = array_sort(array_intersect(FSEvent::getPossibleTypes(), $events), SORT_ASC); + $events = array_intersect(FSEvent::getPossibleTypes(), $events); + asort($events, SORT_ASC); $event = new FSEvent($date, $path, $events); $this->assertTrue(array_diff($event->getTypes(), [FSEvent::Renamed, FSEvent::OwnerModified]) === []); From a03b0ad5b99409c034cc600f48715e77956e61e6 Mon Sep 17 00:00:00 2001 From: Fractal Zombie Date: Mon, 31 Dec 2018 17:04:33 +0200 Subject: [PATCH 028/161] Fix for array_sort. --- src/HotReload/FSEventParser.php | 2 +- tests/HotReload/FSEventTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/HotReload/FSEventParser.php b/src/HotReload/FSEventParser.php index 927e1ff3..4eb0307f 100644 --- a/src/HotReload/FSEventParser.php +++ b/src/HotReload/FSEventParser.php @@ -27,7 +27,7 @@ public static function toEvent(string $event): ?FSEvent $path = $matches[static::PATH]; $events = explode(' ', $matches[static::EVENTS]); $events = array_intersect(FSEvent::getPossibleTypes(), $events); - asort($events, SORT_ASC); + asort($events); return new FSEvent($date, $path, $events); } diff --git a/tests/HotReload/FSEventTest.php b/tests/HotReload/FSEventTest.php index 7a3ef0a4..65fef901 100644 --- a/tests/HotReload/FSEventTest.php +++ b/tests/HotReload/FSEventTest.php @@ -17,7 +17,7 @@ public function testObjectIsCorrect() $path = '/Some/Path/To/File/File.php'; $events = explode(' ', 'Renamed OwnerModified IsFile'); $events = array_intersect(FSEvent::getPossibleTypes(), $events); - asort($events, SORT_ASC); + asort($events); $event = new FSEvent($date, $path, $events); $this->assertTrue(array_diff($event->getTypes(), [FSEvent::Renamed, FSEvent::OwnerModified]) === []); From d80386487869fd1bff62bc6051a3acf3b25fdb82 Mon Sep 17 00:00:00 2001 From: Fractal Zombie Date: Mon, 31 Dec 2018 17:25:33 +0200 Subject: [PATCH 029/161] Added test for FSProcess --- src/HotReload/FSProcess.php | 8 +++--- tests/HotReload/FSProcessTest.php | 45 +++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 tests/HotReload/FSProcessTest.php diff --git a/src/HotReload/FSProcess.php b/src/HotReload/FSProcess.php index b02bc26d..fc946122 100644 --- a/src/HotReload/FSProcess.php +++ b/src/HotReload/FSProcess.php @@ -7,8 +7,6 @@ /** * Class FSProcess - * - * @codeCoverageIgnore */ class FSProcess { @@ -22,7 +20,7 @@ class FSProcess /** * Watch recursively. * - * @var string + * @var bool */ protected $recursively; @@ -44,10 +42,10 @@ class FSProcess * FSProcess constructor. * * @param string $filter - * @param string $recursively + * @param bool $recursively * @param string $directory */ - public function __construct(string $filter, string $recursively, string $directory) + public function __construct(string $filter, bool $recursively, string $directory) { $this->filter = $filter; $this->recursively = $recursively; diff --git a/tests/HotReload/FSProcessTest.php b/tests/HotReload/FSProcessTest.php new file mode 100644 index 00000000..f14ae922 --- /dev/null +++ b/tests/HotReload/FSProcessTest.php @@ -0,0 +1,45 @@ +assertInstanceOf(FSProcess::class, $process); + $this->assertInstanceOf(Process::class, $process->make()); + } + + public function testItCanCreateHotReloadProcessWithNeededConfiguration() + { + $process = new FSProcess('.php', true, base_path()); + $ref = new \ReflectionClass($process); + $configure = $ref->getMethod('configure'); + $configure->setAccessible(true); + $configuration = $configure->invoke($process); + $sampleConfiguration = [ + 'fswatch', + '-rtx', + '-e', + '.*', + '-i', + "\\.php$", + base_path(), + ]; + + $this->assertInstanceOf(FSProcess::class, $process); + $this->assertInstanceOf(Process::class, $process->make()); + $this->assertTrue( + array_diff($sampleConfiguration, $configuration) === [] + ); + } +} \ No newline at end of file From 76332214ed51ddb9cd2fcb4d4d537a1b019c241a Mon Sep 17 00:00:00 2001 From: Fractal Zombie Date: Mon, 31 Dec 2018 17:33:51 +0200 Subject: [PATCH 030/161] Added test for FSProcess --- tests/HotReload/FSProcessTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/HotReload/FSProcessTest.php b/tests/HotReload/FSProcessTest.php index f14ae922..8d3eb200 100644 --- a/tests/HotReload/FSProcessTest.php +++ b/tests/HotReload/FSProcessTest.php @@ -13,7 +13,7 @@ class FSProcessTest extends TestCase { public function testItCanCreateHotReloadProcess() { - $process = new FSProcess('.php', true, base_path()); + $process = new FSProcess('.php', true, __DIR__); $this->assertInstanceOf(FSProcess::class, $process); $this->assertInstanceOf(Process::class, $process->make()); @@ -21,7 +21,7 @@ public function testItCanCreateHotReloadProcess() public function testItCanCreateHotReloadProcessWithNeededConfiguration() { - $process = new FSProcess('.php', true, base_path()); + $process = new FSProcess('.php', true, __DIR__); $ref = new \ReflectionClass($process); $configure = $ref->getMethod('configure'); $configure->setAccessible(true); From 940f8dc7207a7d350c7533ba34319115a7b91a94 Mon Sep 17 00:00:00 2001 From: Fractal Zombie Date: Mon, 31 Dec 2018 17:38:29 +0200 Subject: [PATCH 031/161] Added test for FSProcess --- tests/HotReload/FSProcessTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/HotReload/FSProcessTest.php b/tests/HotReload/FSProcessTest.php index 8d3eb200..c4c7b858 100644 --- a/tests/HotReload/FSProcessTest.php +++ b/tests/HotReload/FSProcessTest.php @@ -33,7 +33,7 @@ public function testItCanCreateHotReloadProcessWithNeededConfiguration() '.*', '-i', "\\.php$", - base_path(), + __DIR__, ]; $this->assertInstanceOf(FSProcess::class, $process); From a0c1f869b875b9da73670c7052240b2226606b6d Mon Sep 17 00:00:00 2001 From: Fractal Zombie Date: Mon, 31 Dec 2018 18:02:01 +0200 Subject: [PATCH 032/161] Added locked check --- src/HotReload/FSProcess.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HotReload/FSProcess.php b/src/HotReload/FSProcess.php index fc946122..4747d07b 100644 --- a/src/HotReload/FSProcess.php +++ b/src/HotReload/FSProcess.php @@ -63,7 +63,7 @@ public function __construct(string $filter, bool $recursively, string $directory public function make(?callable $callback = null) { $mcb = function ($type, $buffer) use ($callback) { - if (AppProcess::OUT === $type && $event = FSEventParser::toEvent($buffer)) { + if (! $this->locked && AppProcess::OUT === $type && $event = FSEventParser::toEvent($buffer)) { $this->locked = true; ($callback) ? $callback($event) : null; $this->locked = false; From e57125df9ec7704fb6895627ecc06a18e3305ebb Mon Sep 17 00:00:00 2001 From: Fractal Zombie Date: Mon, 7 Jan 2019 23:42:40 +0200 Subject: [PATCH 033/161] Fixed FSEventParser REGEX. I don't know why, but fswatch has two spaces when date is less then 10 --- src/HotReload/FSEventParser.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/HotReload/FSEventParser.php b/src/HotReload/FSEventParser.php index 4eb0307f..6ad1aba0 100644 --- a/src/HotReload/FSEventParser.php +++ b/src/HotReload/FSEventParser.php @@ -9,7 +9,7 @@ */ class FSEventParser { - protected const REGEX = '/^([\S+]{3}\s+[\S+]{3}\s+[\d+]{2}\s+[\d+]{2}:[\d+]{2}:{0,2}:[\d+]{2}:{0,2}\s+[\d+]{0,4})\s+(\/[\S+]*)\s+([\S+*\s+]*)/mi'; + protected const REGEX = '/^([\S+]{3}\s+[\S+]{3}\s+[\d+]{1,2}\s+[\d+]{2}:[\d+]{2}:{0,2}:[\d+]{2}:{0,2}\s+[\d+]{0,4})\s*(\/[\S+]*)\s+([\S+*\s+]*)/mi'; protected const DATE = 1; protected const PATH = 2; @@ -29,6 +29,8 @@ public static function toEvent(string $event): ?FSEvent $events = array_intersect(FSEvent::getPossibleTypes(), $events); asort($events); + dd($events, $path, $date); + return new FSEvent($date, $path, $events); } From c50a7140a8e120503e6cd10d15af2805efa45746 Mon Sep 17 00:00:00 2001 From: Fractal Zombie Date: Mon, 7 Jan 2019 23:51:24 +0200 Subject: [PATCH 034/161] Fixed FSEventParser REGEX. I don't know why, but fswatch has two spaces when date is less then 10 --- src/HotReload/FSEventParser.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/HotReload/FSEventParser.php b/src/HotReload/FSEventParser.php index 6ad1aba0..c0c35ef6 100644 --- a/src/HotReload/FSEventParser.php +++ b/src/HotReload/FSEventParser.php @@ -29,8 +29,6 @@ public static function toEvent(string $event): ?FSEvent $events = array_intersect(FSEvent::getPossibleTypes(), $events); asort($events); - dd($events, $path, $date); - return new FSEvent($date, $path, $events); } From f5e3651953942d1971405cc870de69a4bc1d4aa7 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Wed, 9 Jan 2019 23:31:01 +0800 Subject: [PATCH 035/161] fix params for websocket's onOpen function --- src/Concerns/InteractsWithWebsocket.php | 5 +++-- src/Server/Manager.php | 7 +++---- tests/Server/ManagerTest.php | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Concerns/InteractsWithWebsocket.php b/src/Concerns/InteractsWithWebsocket.php index 3521bc53..71406579 100644 --- a/src/Concerns/InteractsWithWebsocket.php +++ b/src/Concerns/InteractsWithWebsocket.php @@ -51,9 +51,10 @@ trait InteractsWithWebsocket /** * "onOpen" listener. * + * @param \Swoole\Websocket\Server $server * @param \Swoole\Http\Request $swooleRequest */ - public function onOpen($swooleRequest) + public function onOpen($server, $swooleRequest) { $illuminateRequest = Request::make($swooleRequest)->toIlluminate(); $websocket = $this->app->make(Websocket::class); @@ -212,7 +213,7 @@ protected function prepareWebsocket() $parser = $config->get('swoole_websocket.parser'); if ($isWebsocket) { - $this->types = array_merge($this->types ?? [], $this->wsEvents); + $this->events = array_merge($this->events ?? [], $this->wsEvents); $this->isServerWebsocket = true; $this->setPayloadParser(new $parser); } diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 7d82e8ef..1e307c4c 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -5,7 +5,6 @@ use Exception; use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Debug\ExceptionHandler; -use Illuminate\Events\Dispatcher; use Illuminate\Support\Facades\Facade; use Illuminate\Support\Str; use Swoole\Process; @@ -146,7 +145,7 @@ public function onStart() public function onManagerStart() { $this->setProcessName('manager process'); - $this->container->make(Dispatcher::class)->fire('swoole.managerStart', func_get_args()); + $this->container->make('events')->fire('swoole.managerStart', func_get_args()); } /** @@ -197,7 +196,7 @@ public function onRequest($swooleRequest, $swooleResponse) $this->app->make('events')->fire('swoole.request'); $this->resetOnRequest(); - $sandbox = $this->app->make(Sandbox::class);; + $sandbox = $this->app->make(Sandbox::class); $handleStatic = $this->container->make('config')->get('swoole_http.handle_static_files', true); $publicPath = $this->container->make('config')->get('swoole_http.server.public_path', base_path('public')); @@ -264,7 +263,7 @@ public function onTask($server, $taskId, $srcWorkerId, $data) && $data['action'] === Websocket::PUSH_ACTION) { $this->pushMessage($server, $data['data'] ?? []); } - // push async task to queue + // push async task to queue } else { if (is_string($data)) { $decoded = \json_decode($data, true); diff --git a/tests/Server/ManagerTest.php b/tests/Server/ManagerTest.php index 0664c861..521f16a2 100644 --- a/tests/Server/ManagerTest.php +++ b/tests/Server/ManagerTest.php @@ -420,7 +420,7 @@ public function testOnOpen() $manager = $this->getWebsocketManager(); $manager->setApplication($container); $manager->setWebsocketHandler($handler); - $manager->onOpen($request); + $manager->onOpen(m::mock('server'), $request); } public function testOnMessage() From 04a32c87f986ea70cd8440562f1b7b7f987415e9 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Wed, 9 Jan 2019 23:31:47 +0800 Subject: [PATCH 036/161] adjust stub files --- stubs/5.5/MySqlConnector.stub | 1 - stubs/5.6/MySqlConnector.stub | 1 - stubs/5.6/SwooleTaskQueue.stub | 3 +-- stubs/5.7/SwooleTaskQueue.stub | 3 +-- tests/Task/QueueFactoryTest.php | 1 - 5 files changed, 2 insertions(+), 7 deletions(-) diff --git a/stubs/5.5/MySqlConnector.stub b/stubs/5.5/MySqlConnector.stub index 45281ac0..13315b10 100644 --- a/stubs/5.5/MySqlConnector.stub +++ b/stubs/5.5/MySqlConnector.stub @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Coroutine\Connectors; - use Illuminate\Database\Connectors\MySqlConnector as BaseConnector; use Illuminate\Support\Str; use SwooleTW\Http\Coroutine\PDO as SwoolePDO; diff --git a/stubs/5.6/MySqlConnector.stub b/stubs/5.6/MySqlConnector.stub index 7082d761..2efa720a 100644 --- a/stubs/5.6/MySqlConnector.stub +++ b/stubs/5.6/MySqlConnector.stub @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Coroutine\Connectors; - use Illuminate\Database\Connectors\MySqlConnector as BaseConnector; use Illuminate\Support\Str; use SwooleTW\Http\Coroutine\PDO as SwoolePDO; diff --git a/stubs/5.6/SwooleTaskQueue.stub b/stubs/5.6/SwooleTaskQueue.stub index 82c161d4..2e331e8d 100644 --- a/stubs/5.6/SwooleTaskQueue.stub +++ b/stubs/5.6/SwooleTaskQueue.stub @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Task; - use Exception; use Illuminate\Contracts\Queue\Queue as QueueContract; use Illuminate\Queue\Queue; @@ -55,7 +54,7 @@ class SwooleTaskQueue extends Queue implements QueueContract */ public function pushRaw($payload, $queue = null, array $options = []) { - return $this->swoole->task($payload, !is_numeric($queue) ? -1 : (int)$queue); + return $this->swoole->task($payload, ! is_numeric($queue) ? -1 : (int)$queue); } /** diff --git a/stubs/5.7/SwooleTaskQueue.stub b/stubs/5.7/SwooleTaskQueue.stub index b71d2f01..5eb0e73d 100644 --- a/stubs/5.7/SwooleTaskQueue.stub +++ b/stubs/5.7/SwooleTaskQueue.stub @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Task; - use Exception; use Illuminate\Contracts\Queue\Queue as QueueContract; use Illuminate\Queue\Queue; @@ -55,7 +54,7 @@ class SwooleTaskQueue extends Queue implements QueueContract */ public function pushRaw($payload, $queue = null, array $options = []) { - return $this->swoole->task($payload, !is_numeric($queue) ? -1 : (int)$queue); + return $this->swoole->task($payload, ! is_numeric($queue) ? -1 : (int)$queue); } /** diff --git a/tests/Task/QueueFactoryTest.php b/tests/Task/QueueFactoryTest.php index 0f27937e..c41ee211 100644 --- a/tests/Task/QueueFactoryTest.php +++ b/tests/Task/QueueFactoryTest.php @@ -48,7 +48,6 @@ public function testItCanMakeNeededQueueByVersion() protected function getServer() { $server = m::mock('server'); -// $server->shouldReceive('on'); $server->taskworker = false; $server->master_pid = -1; From 47f9643e50fed901a510adf50f24876d6a874c30 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Wed, 9 Jan 2019 23:38:15 +0800 Subject: [PATCH 037/161] fix return type for make function of QueueFactory --- src/Task/QueueFactory.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Task/QueueFactory.php b/src/Task/QueueFactory.php index 4610827c..99ddc73d 100644 --- a/src/Task/QueueFactory.php +++ b/src/Task/QueueFactory.php @@ -2,9 +2,9 @@ namespace SwooleTW\Http\Task; -use Illuminate\Contracts\Queue\Queue; use Illuminate\Support\Arr; use SwooleTW\Http\Helpers\FW; +use SwooleTW\Http\Task\SwooleTaskQueue; /** * Class QueueFactory @@ -36,9 +36,9 @@ class QueueFactory * @param \Swoole\Http\Server $server * @param string $version * - * @return \Illuminate\Contracts\Queue\Queue + * @return \SwooleTW\Http\Task\SwooleTaskQueue */ - public static function make($server, string $version): Queue + public static function make($server, string $version): SwooleTaskQueue { $isMatch = static::isFileVersionMatch($version); $class = static::copy(static::stub($version), ! $isMatch); From fc9ec99145486009fa73e8d4b2d5909c894f3dee Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 13 Jan 2019 17:23:31 +0800 Subject: [PATCH 038/161] remove alias helper for the consistency with Laravel's convention --- src/Commands/HttpServerCommand.php | 15 +++++----- src/Concerns/InteractsWithWebsocket.php | 28 ++++++++--------- src/Concerns/WithApplication.php | 6 ++-- src/Coroutine/Connectors/MySqlConnector.php | 1 - src/Helpers/Alias.php | 17 ----------- src/Helpers/FW.php | 2 +- src/HttpServiceProvider.php | 33 ++++++++++----------- src/LaravelServiceProvider.php | 3 +- src/LumenServiceProvider.php | 3 +- src/Server/Facades/Sandbox.php | 23 ++++++++++++-- src/Server/Facades/Server.php | 3 +- src/Server/Manager.php | 21 ++++++------- src/Server/Resetters/ResetConfig.php | 2 +- src/Server/Sandbox.php | 10 +++---- src/Table/Facades/SwooleTable.php | 6 +++- src/Task/SwooleTaskQueue.php | 2 +- src/Websocket/Facades/Room.php | 11 +++++-- src/Websocket/Facades/Websocket.php | 29 +++++++++++++++++- src/Websocket/Websocket.php | 10 +++++-- tests/Server/ManagerTest.php | 13 ++++---- tests/Server/ResettersTest.php | 9 +++--- 21 files changed, 142 insertions(+), 105 deletions(-) delete mode 100644 src/Helpers/Alias.php diff --git a/src/Commands/HttpServerCommand.php b/src/Commands/HttpServerCommand.php index 4422866f..b964207d 100644 --- a/src/Commands/HttpServerCommand.php +++ b/src/Commands/HttpServerCommand.php @@ -2,21 +2,20 @@ namespace SwooleTW\Http\Commands; +use Throwable; +use Swoole\Process; +use Illuminate\Support\Arr; use Illuminate\Console\Command; +use SwooleTW\Http\Server\Manager; use Illuminate\Console\OutputStyle; -use Illuminate\Contracts\Container\Container; -use Illuminate\Support\Arr; -use Swoole\Process; -use SwooleTW\Http\Helpers\Alias; use SwooleTW\Http\HotReload\FSEvent; +use SwooleTW\Http\Server\AccessOutput; use SwooleTW\Http\HotReload\FSOutput; use SwooleTW\Http\HotReload\FSProcess; use SwooleTW\Http\Middlewares\AccessLog; -use SwooleTW\Http\Server\AccessOutput; use SwooleTW\Http\Server\Facades\Server; -use SwooleTW\Http\Server\Manager; +use Illuminate\Contracts\Container\Container; use Symfony\Component\Console\Output\ConsoleOutput; -use Throwable; /** * @codeCoverageIgnore @@ -77,7 +76,7 @@ public function handle() */ protected function loadConfigs() { - $this->config = $this->laravel->make(Alias::CONFIG)->get('swoole_http'); + $this->config = $this->laravel->make('config')->get('swoole_http'); } /** diff --git a/src/Concerns/InteractsWithWebsocket.php b/src/Concerns/InteractsWithWebsocket.php index 71406579..90f202e4 100644 --- a/src/Concerns/InteractsWithWebsocket.php +++ b/src/Concerns/InteractsWithWebsocket.php @@ -2,20 +2,19 @@ namespace SwooleTW\Http\Concerns; -use Illuminate\Contracts\Container\Container; -use Illuminate\Pipeline\Pipeline; +use Throwable; use Illuminate\Support\Arr; -use SwooleTW\Http\Exceptions\WebsocketNotSetInConfigException; -use SwooleTW\Http\Helpers\Alias; -use SwooleTW\Http\Server\Facades\Server; +use Illuminate\Pipeline\Pipeline; use SwooleTW\Http\Server\Sandbox; +use SwooleTW\Http\Websocket\Push; +use SwooleTW\Http\Websocket\Parser; +use SwooleTW\Http\Websocket\Websocket; use SwooleTW\Http\Transformers\Request; +use SwooleTW\Http\Server\Facades\Server; use SwooleTW\Http\Websocket\HandlerContract; -use SwooleTW\Http\Websocket\Parser; -use SwooleTW\Http\Websocket\Push; +use Illuminate\Contracts\Container\Container; use SwooleTW\Http\Websocket\Rooms\RoomContract; -use SwooleTW\Http\Websocket\Websocket; -use Throwable; +use SwooleTW\Http\Exceptions\WebsocketNotSetInConfigException; /** * Trait InteractsWithWebsocket @@ -208,7 +207,7 @@ public function getPayloadParser() */ protected function prepareWebsocket() { - $config = $this->container->make(Alias::CONFIG); + $config = $this->container->make('config'); $isWebsocket = $config->get('swoole_http.websocket.enabled'); $parser = $config->get('swoole_websocket.parser'); @@ -256,7 +255,7 @@ protected function filterWebsocket(array $descriptors): array */ protected function prepareWebsocketHandler() { - $handlerClass = $this->container->make(Alias::CONFIG)->get('swoole_websocket.handler'); + $handlerClass = $this->container->make('config')->get('swoole_websocket.handler'); if (! $handlerClass) { throw new WebsocketNotSetInConfigException; @@ -306,7 +305,7 @@ protected function createRoom(string $class, array $settings): RoomContract protected function bindRoom(): void { $this->app->singleton(RoomContract::class, function (Container $container) { - $config = $container->make(Alias::CONFIG); + $config = $container->make('config'); $driver = $config->get('swoole_websocket.default'); $settings = $config->get("swoole_websocket.settings.{$driver}"); $className = $config->get("swoole_websocket.drivers.{$driver}"); @@ -314,7 +313,7 @@ protected function bindRoom(): void return $this->createRoom($className, $settings); }); - $this->app->alias(RoomContract::class, Alias::ROOM); + $this->app->alias(RoomContract::class, 'swoole.room'); } /** @@ -334,7 +333,8 @@ protected function bindWebsocket() */ protected function loadWebsocketRoutes() { - $routePath = $this->container->make(Alias::CONFIG)->get('swoole_websocket.route_file'); + $routePath = $this->container->make('config') + ->get('swoole_websocket.route_file'); if (! file_exists($routePath)) { $routePath = __DIR__ . '/../../routes/websocket.php'; diff --git a/src/Concerns/WithApplication.php b/src/Concerns/WithApplication.php index 3c56512d..6ead455f 100644 --- a/src/Concerns/WithApplication.php +++ b/src/Concerns/WithApplication.php @@ -2,11 +2,10 @@ namespace SwooleTW\Http\Concerns; -use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Http\Kernel; use Illuminate\Support\Facades\Facade; +use Illuminate\Contracts\Container\Container; use SwooleTW\Http\Exceptions\FrameworkNotSupportException; -use SwooleTW\Http\Helpers\Alias; /** * Trait WithApplication @@ -149,7 +148,8 @@ public function getBasePath() */ protected function preResolveInstances() { - $resolves = $this->container->make(Alias::CONFIG)->get('swoole_http.pre_resolved', []); + $resolves = $this->container->make('config') + ->get('swoole_http.pre_resolved', []); foreach ($resolves as $abstract) { if ($this->getApplication()->offsetExists($abstract)) { diff --git a/src/Coroutine/Connectors/MySqlConnector.php b/src/Coroutine/Connectors/MySqlConnector.php index 7082d761..2efa720a 100644 --- a/src/Coroutine/Connectors/MySqlConnector.php +++ b/src/Coroutine/Connectors/MySqlConnector.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Coroutine\Connectors; - use Illuminate\Database\Connectors\MySqlConnector as BaseConnector; use Illuminate\Support\Str; use SwooleTW\Http\Coroutine\PDO as SwoolePDO; diff --git a/src/Helpers/Alias.php b/src/Helpers/Alias.php deleted file mode 100644 index 96e53256..00000000 --- a/src/Helpers/Alias.php +++ /dev/null @@ -1,17 +0,0 @@ - base_path('routes/websocket.php'), ], 'laravel-swoole'); - $config = $this->app->make(Alias::CONFIG); + $config = $this->app->make('config'); if ($config->get('swoole_http.websocket.enabled')) { $this->bootRoutes(); @@ -91,7 +90,6 @@ public function boot() if ($config->get('swoole_http.server.access_log')) { $this->app->make(Kernel::class)->pushMiddleware(AccessLog::class); -// dd($this->app->make(Kernel::class)); } } @@ -109,7 +107,8 @@ protected function mergeConfigs() */ protected function setIsWebsocket() { - $this->isWebsocket = $this->app->make(Alias::CONFIG)->get('swoole_http.websocket.enabled'); + $this->isWebsocket = $this->app->make('config') + ->get('swoole_http.websocket.enabled'); } /** @@ -128,7 +127,7 @@ protected function registerCommands() protected function createSwooleServer() { $server = $this->isWebsocket ? WebsocketServer::class : HttpServer::class; - $config = $this->app->make(Alias::CONFIG); + $config = $this->app->make('config'); $host = $config->get('swoole_http.server.host'); $port = $config->get('swoole_http.server.port'); $socketType = $config->get('swoole_http.server.socket_type', SWOOLE_SOCK_TCP); @@ -142,7 +141,7 @@ protected function createSwooleServer() */ protected function configureSwooleServer() { - $config = $this->app->make(Alias::CONFIG); + $config = $this->app->make('config'); $options = $config->get('swoole_http.server.options'); // only enable task worker in websocket mode and for queue driver @@ -168,7 +167,7 @@ protected function registerServer() return static::$server; }); - $this->app->alias(Server::class, Alias::SERVER); + $this->app->alias(Server::class, 'swoole.server'); } /** @@ -233,7 +232,7 @@ protected function getNewMySqlConnection(array $config) */ protected function registerSwooleQueueDriver() { - $this->app->afterResolving(Alias::QUEUE, function (QueueManager $manager) { + $this->app->afterResolving('queue', function (QueueManager $manager) { $manager->addConnector('swoole', function () { return new SwooleTaskConnector($this->app->make(Server::class)); }); diff --git a/src/LaravelServiceProvider.php b/src/LaravelServiceProvider.php index 711ead56..d21b26f4 100644 --- a/src/LaravelServiceProvider.php +++ b/src/LaravelServiceProvider.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http; -use SwooleTW\Http\Helpers\Alias; use SwooleTW\Http\Server\Manager; /** @@ -21,7 +20,7 @@ protected function registerManager() return new Manager($app, 'laravel'); }); - $this->app->alias(Manager::class, Alias::MANAGER); + $this->app->alias(Manager::class, 'swoole.manager'); } /** diff --git a/src/LumenServiceProvider.php b/src/LumenServiceProvider.php index 499af4bc..e29f948c 100644 --- a/src/LumenServiceProvider.php +++ b/src/LumenServiceProvider.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http; -use SwooleTW\Http\Helpers\Alias; use SwooleTW\Http\Server\Manager; /** @@ -21,7 +20,7 @@ protected function registerManager() return new Manager($app, 'lumen'); }); - $this->app->alias(Manager::class, Alias::MANAGER); + $this->app->alias(Manager::class, 'swoole.manager'); } /** diff --git a/src/Server/Facades/Sandbox.php b/src/Server/Facades/Sandbox.php index 8cee44dd..6dd2bd4f 100644 --- a/src/Server/Facades/Sandbox.php +++ b/src/Server/Facades/Sandbox.php @@ -3,8 +3,27 @@ namespace SwooleTW\Http\Server\Facades; use Illuminate\Support\Facades\Facade; -use SwooleTW\Http\Helpers\Alias; +/** + * @method static this setFramework($framework) + * @method static string getFramework() + * @method static this setBaseApp($app) + * @method static \Illuminate\Container\Container getBaseApp() + * @method static \Illuminate\Container\Container getApplication() + * @method static this setRequest($request) + * @method static \Illuminate\Http\Request getRequest($request) + * @method static \Illuminate\Http\Response run() + * @method static this setSnapshot($snapshot) + * @method static \Illuminate\Container\Container getSnapshot() + * @method static this initialize() + * @method static boolean isLaravel() + * @method static void terminate($request, $response) + * @method static void enable() + * @method static void disable() + * @method static void setInstance($app) + * + * @see \SwooleTW\Http\Server\Sandbox + */ class Sandbox extends Facade { /** @@ -14,6 +33,6 @@ class Sandbox extends Facade */ protected static function getFacadeAccessor() { - return Alias::SANDBOX; + return 'swoole.sandbox'; } } \ No newline at end of file diff --git a/src/Server/Facades/Server.php b/src/Server/Facades/Server.php index 4dd8195a..eb422aa3 100644 --- a/src/Server/Facades/Server.php +++ b/src/Server/Facades/Server.php @@ -3,7 +3,6 @@ namespace SwooleTW\Http\Server\Facades; use Illuminate\Support\Facades\Facade; -use SwooleTW\Http\Helpers\Alias; /** * Class Server @@ -19,6 +18,6 @@ class Server extends Facade */ protected static function getFacadeAccessor() { - return Alias::SERVER; + return 'swoole.server'; } } \ No newline at end of file diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 1e307c4c..90e43d66 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -3,22 +3,23 @@ namespace SwooleTW\Http\Server; use Exception; -use Illuminate\Contracts\Container\Container; -use Illuminate\Contracts\Debug\ExceptionHandler; -use Illuminate\Support\Facades\Facade; -use Illuminate\Support\Str; +use Throwable; use Swoole\Process; -use SwooleTW\Http\Concerns\InteractsWithSwooleTable; -use SwooleTW\Http\Concerns\InteractsWithWebsocket; -use SwooleTW\Http\Concerns\WithApplication; +use Illuminate\Support\Str; use SwooleTW\Http\Helpers\OS; -use SwooleTW\Http\Server\Facades\Server; +use SwooleTW\Http\Server\Sandbox; use SwooleTW\Http\Task\SwooleTaskJob; +use Illuminate\Support\Facades\Facade; +use SwooleTW\Http\Websocket\Websocket; use SwooleTW\Http\Transformers\Request; +use SwooleTW\Http\Server\Facades\Server; use SwooleTW\Http\Transformers\Response; -use SwooleTW\Http\Websocket\Websocket; +use SwooleTW\Http\Concerns\WithApplication; +use Illuminate\Contracts\Container\Container; +use Illuminate\Contracts\Debug\ExceptionHandler; +use SwooleTW\Http\Concerns\InteractsWithWebsocket; +use SwooleTW\Http\Concerns\InteractsWithSwooleTable; use Symfony\Component\Debug\Exception\FatalThrowableError; -use Throwable; /** * Class Manager diff --git a/src/Server/Resetters/ResetConfig.php b/src/Server/Resetters/ResetConfig.php index 24cea3aa..beb44b7d 100644 --- a/src/Server/Resetters/ResetConfig.php +++ b/src/Server/Resetters/ResetConfig.php @@ -2,8 +2,8 @@ namespace SwooleTW\Http\Server\Resetters; -use Illuminate\Contracts\Container\Container; use SwooleTW\Http\Server\Sandbox; +use Illuminate\Contracts\Container\Container; class ResetConfig implements ResetterContract { diff --git a/src/Server/Sandbox.php b/src/Server/Sandbox.php index 29c50bb1..5bf878e1 100644 --- a/src/Server/Sandbox.php +++ b/src/Server/Sandbox.php @@ -2,18 +2,18 @@ namespace SwooleTW\Http\Server; +use Illuminate\Http\Request; use Illuminate\Container\Container; -use Illuminate\Contracts\Config\Repository as ConfigContract; +use SwooleTW\Http\Coroutine\Context; use Illuminate\Contracts\Http\Kernel; -use Illuminate\Http\Request; use Illuminate\Support\Facades\Facade; -use Laravel\Lumen\Application as LumenApplication; use SwooleTW\Http\Concerns\ResetApplication; -use SwooleTW\Http\Coroutine\Context; use SwooleTW\Http\Exceptions\SandboxException; +use Laravel\Lumen\Application as LumenApplication; +use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpFoundation\BinaryFileResponse; +use Illuminate\Contracts\Config\Repository as ConfigContract; use Symfony\Component\HttpFoundation\Response as SymfonyResponse; -use Symfony\Component\HttpFoundation\StreamedResponse; class Sandbox { diff --git a/src/Table/Facades/SwooleTable.php b/src/Table/Facades/SwooleTable.php index e9f9de11..67510a2a 100644 --- a/src/Table/Facades/SwooleTable.php +++ b/src/Table/Facades/SwooleTable.php @@ -5,7 +5,11 @@ use Illuminate\Support\Facades\Facade; /** - * Class SwooleTable + * @method static \SwooleTW\Http\Table\SwooleTable add($name, $table) + * @method static \Swoole\Table get($name) + * @method static array getAll() + * + * @see \SwooleTW\Http\Table\SwooleTable */ class SwooleTable extends Facade { diff --git a/src/Task/SwooleTaskQueue.php b/src/Task/SwooleTaskQueue.php index 6d2fb32c..5eb0e73d 100644 --- a/src/Task/SwooleTaskQueue.php +++ b/src/Task/SwooleTaskQueue.php @@ -54,7 +54,7 @@ public function push($job, $data = '', $queue = null) */ public function pushRaw($payload, $queue = null, array $options = []) { - return $this->swoole->task($payload, ! is_numeric($queue) ? 1 : (int) $queue); + return $this->swoole->task($payload, ! is_numeric($queue) ? -1 : (int)$queue); } /** diff --git a/src/Websocket/Facades/Room.php b/src/Websocket/Facades/Room.php index d09d7e82..5b1919c2 100644 --- a/src/Websocket/Facades/Room.php +++ b/src/Websocket/Facades/Room.php @@ -3,10 +3,15 @@ namespace SwooleTW\Http\Websocket\Facades; use Illuminate\Support\Facades\Facade; -use SwooleTW\Http\Helpers\Alias; /** - * Class Room + * @method static this prepare() + * @method static this add($fd, $rooms) + * @method static this delete($fd, $rooms) + * @method static array getClients($room) + * @method static array getRooms($fd) + * + * @see \SwooleTW\Http\Websocket\Rooms\RoomContract */ class Room extends Facade { @@ -17,6 +22,6 @@ class Room extends Facade */ protected static function getFacadeAccessor() { - return Alias::ROOM; + return 'swoole.room'; } } \ No newline at end of file diff --git a/src/Websocket/Facades/Websocket.php b/src/Websocket/Facades/Websocket.php index 5dcc4f05..9f054036 100644 --- a/src/Websocket/Facades/Websocket.php +++ b/src/Websocket/Facades/Websocket.php @@ -5,7 +5,34 @@ use Illuminate\Support\Facades\Facade; /** - * Class Websocket + * @method static this broadcast() + * @method static this to($values) + * @method static this join($rooms) + * @method static this leave($rooms) + * @method static boolean emit($event, $data) + * @method static this in($room) + * @method static this on($event, $callback) + * @method static boolean eventExists($event) + * @method static mixed call($event, $data) + * @method static boolean close($fd) + * @method static this setSender($fd) + * @method static int getSender() + * @method static boolean getIsBroadcast() + * @method static array getTo() + * @method static this reset() + * @method static this middleware($middleware) + * @method static this setContainer($container) + * @method static this setPipeline($pipeline) + * @method static \Illuminate\Contracts\Pipeline\Pipeline getPipeline() + * @method static mixed loginUsing($user) + * @method static this loginUsingId($userId) + * @method static this logout() + * @method static this toUser($users) + * @method static this toUserId($userIds) + * @method static string getUserId() + * @method static boolean isUserIdOnline($userId) + * + * @see \SwooleTW\Http\Websocket\Websocket */ class Websocket extends Facade { diff --git a/src/Websocket/Websocket.php b/src/Websocket/Websocket.php index 2ef95179..18fe56bd 100644 --- a/src/Websocket/Websocket.php +++ b/src/Websocket/Websocket.php @@ -93,7 +93,7 @@ public function __construct(RoomContract $room, PipelineContract $pipeline) /** * Set broadcast to true. */ - public function broadcast() + public function broadcast(): self { $this->isBroadcast = true; @@ -343,7 +343,7 @@ protected function getFds() * * @param bool $force * - * @return \SwooleTW\Http\Websocket\Websocket + * @return $this */ public function reset($force = false) { @@ -392,6 +392,8 @@ protected function setDefaultMiddleware() * Set container to pipeline. * * @param \Illuminate\Contracts\Container\Container $container + * + * @return $this */ public function setContainer(Container $container) { @@ -403,6 +405,8 @@ public function setContainer(Container $container) $resetPipeline = $closure->bindTo($pipeline, $pipeline); $resetPipeline(); + + return $this; } /** @@ -410,7 +414,7 @@ public function setContainer(Container $container) * * @param \Illuminate\Contracts\Pipeline\Pipeline $pipeline * - * @return \SwooleTW\Http\Websocket\Websocket + * @return $this */ public function setPipeline(PipelineContract $pipeline) { diff --git a/tests/Server/ManagerTest.php b/tests/Server/ManagerTest.php index 521f16a2..fab6ab3f 100644 --- a/tests/Server/ManagerTest.php +++ b/tests/Server/ManagerTest.php @@ -3,7 +3,6 @@ namespace SwooleTW\Http\Tests\Server; use Illuminate\Container\Container; -use Illuminate\Contracts\Config\Repository; use Illuminate\Contracts\Debug\ExceptionHandler; use Illuminate\Support\Facades\Config; use Laravel\Lumen\Exceptions\Handler; @@ -11,7 +10,6 @@ use Swoole\Http\Request; use Swoole\Http\Response; use Swoole\Table; -use SwooleTW\Http\Helpers\Alias; use SwooleTW\Http\Server\Facades\Server; use SwooleTW\Http\Server\Manager; use SwooleTW\Http\Server\Sandbox; @@ -25,6 +23,7 @@ use SwooleTW\Http\Websocket\SocketIO\SocketIOParser; use SwooleTW\Http\Websocket\SocketIO\WebsocketHandler; use SwooleTW\Http\Websocket\Websocket; +use Illuminate\Contracts\Config\Repository as ConfigContract; class ManagerTest extends TestCase { @@ -524,7 +523,7 @@ public function testOnClose() return $server; }); - $container->alias(Server::class, Alias::SERVER); + $container->alias(Server::class, 'swoole.server'); $manager = $this->getWebsocketManager($container); $manager->setApplication($app); @@ -597,15 +596,15 @@ protected function getContainer($server = null, $config = null) $config = $config ?? $this->getConfig(); $container = new Container; - $container->singleton(Repository::class, function () use ($config) { + $container->singleton(ConfigContract::class, function () use ($config) { return $config; }); - $container->alias(Repository::class, Alias::CONFIG); + $container->alias(ConfigContract::class, 'config'); $container->singleton(Server::class, function () use ($server) { return $server; }); - $container->alias(Server::class, Alias::SERVER); + $container->alias(Server::class, 'swoole.server'); $container->singleton(ExceptionHandler::class, Handler::class); return $container; @@ -623,7 +622,7 @@ protected function getServer() protected function getConfig($websocket = false) { - $config = m::mock(Repository::class); + $config = m::mock(ConfigContract::class); $settings = $websocket ? 'websocketConfig' : 'config'; $callback = function ($key) use ($settings) { return $this->$settings[$key] ?? ''; diff --git a/tests/Server/ResettersTest.php b/tests/Server/ResettersTest.php index e5ef0bcb..a90d2283 100644 --- a/tests/Server/ResettersTest.php +++ b/tests/Server/ResettersTest.php @@ -3,12 +3,11 @@ namespace SwooleTW\Http\Tests\Server; use Illuminate\Container\Container; -use Illuminate\Contracts\Config\Repository; +use Illuminate\Contracts\Config\Repository as ConfigContract; use Illuminate\Contracts\Http\Kernel; use Illuminate\Http\Request; use Illuminate\Support\ServiceProvider; use Mockery as m; -use SwooleTW\Http\Helpers\Alias; use SwooleTW\Http\Server\Resetters\BindRequest; use SwooleTW\Http\Server\Resetters\ClearInstances; use SwooleTW\Http\Server\Resetters\RebindKernelContainer; @@ -158,7 +157,7 @@ public function testRebindViewContainer() public function testResetConfig() { - $config = m::mock(Repository::class); + $config = m::mock(ConfigContract::class); $sandbox = m::mock(Sandbox::class); $sandbox->shouldReceive('getConfig') ->once() @@ -168,7 +167,7 @@ public function testResetConfig() $resetter = new ResetConfig; $app = $resetter->handle($container, $sandbox); - $this->assertSame(get_class($config), get_class($app->make(Alias::CONFIG))); + $this->assertSame(get_class($config), get_class($app->make('config'))); } public function testResetCookie() @@ -239,9 +238,11 @@ class TestProvider extends ServiceProvider { public function register() { + // } public function boot() { + // } } From 29014dca4a39fadfff66ea03fb25c1e0fc53dd72 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 13 Jan 2019 17:43:10 +0800 Subject: [PATCH 039/161] fix type hinting for QueueManage --- src/HttpServiceProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HttpServiceProvider.php b/src/HttpServiceProvider.php index be175be1..16de78bc 100644 --- a/src/HttpServiceProvider.php +++ b/src/HttpServiceProvider.php @@ -4,7 +4,6 @@ use Illuminate\Support\Arr; use SwooleTW\Http\Helpers\FW; -use Illuminate\Queue\QueueManager; use Illuminate\Contracts\Http\Kernel; use Swoole\Http\Server as HttpServer; use Illuminate\Support\ServiceProvider; @@ -14,6 +13,7 @@ use SwooleTW\Http\Coroutine\MySqlConnection; use SwooleTW\Http\Commands\HttpServerCommand; use Swoole\Websocket\Server as WebsocketServer; +use Illuminate\Queue\Capsule\Manager as QueueManager; use SwooleTW\Http\Task\Connectors\SwooleTaskConnector; use SwooleTW\Http\Coroutine\Connectors\ConnectorFactory; From 62cb989f0151e589e3fd019a26d5563f569a3748 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 13 Jan 2019 17:53:55 +0800 Subject: [PATCH 040/161] remove type hinting for queue manager --- src/HttpServiceProvider.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/HttpServiceProvider.php b/src/HttpServiceProvider.php index 16de78bc..128a8612 100644 --- a/src/HttpServiceProvider.php +++ b/src/HttpServiceProvider.php @@ -13,7 +13,6 @@ use SwooleTW\Http\Coroutine\MySqlConnection; use SwooleTW\Http\Commands\HttpServerCommand; use Swoole\Websocket\Server as WebsocketServer; -use Illuminate\Queue\Capsule\Manager as QueueManager; use SwooleTW\Http\Task\Connectors\SwooleTaskConnector; use SwooleTW\Http\Coroutine\Connectors\ConnectorFactory; @@ -232,7 +231,7 @@ protected function getNewMySqlConnection(array $config) */ protected function registerSwooleQueueDriver() { - $this->app->afterResolving('queue', function (QueueManager $manager) { + $this->app->afterResolving('queue', function ($manager) { $manager->addConnector('swoole', function () { return new SwooleTaskConnector($this->app->make(Server::class)); }); From 675785db4787da7ad187a5a00ce431b4f574346a Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 13 Jan 2019 18:12:05 +0800 Subject: [PATCH 041/161] add type hinting of QueueManager back --- src/HttpServiceProvider.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/HttpServiceProvider.php b/src/HttpServiceProvider.php index 128a8612..be175be1 100644 --- a/src/HttpServiceProvider.php +++ b/src/HttpServiceProvider.php @@ -4,6 +4,7 @@ use Illuminate\Support\Arr; use SwooleTW\Http\Helpers\FW; +use Illuminate\Queue\QueueManager; use Illuminate\Contracts\Http\Kernel; use Swoole\Http\Server as HttpServer; use Illuminate\Support\ServiceProvider; @@ -231,7 +232,7 @@ protected function getNewMySqlConnection(array $config) */ protected function registerSwooleQueueDriver() { - $this->app->afterResolving('queue', function ($manager) { + $this->app->afterResolving('queue', function (QueueManager $manager) { $manager->addConnector('swoole', function () { return new SwooleTaskConnector($this->app->make(Server::class)); }); From d225cef8f7a1ede9fbc99eba5a5c244e8910b22c Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 13 Jan 2019 18:22:35 +0800 Subject: [PATCH 042/161] fix type hint for access log in case of JsonResponse --- src/Commands/HttpServerCommand.php | 2 +- src/HttpServiceProvider.php | 2 +- src/{Middlewares => Middleware}/AccessLog.php | 6 +++--- src/Server/AccessOutput.php | 4 ++-- tests/Websocket/WebsocketTest.php | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) rename src/{Middlewares => Middleware}/AccessLog.php (86%) diff --git a/src/Commands/HttpServerCommand.php b/src/Commands/HttpServerCommand.php index b964207d..2d1ab105 100644 --- a/src/Commands/HttpServerCommand.php +++ b/src/Commands/HttpServerCommand.php @@ -12,7 +12,7 @@ use SwooleTW\Http\Server\AccessOutput; use SwooleTW\Http\HotReload\FSOutput; use SwooleTW\Http\HotReload\FSProcess; -use SwooleTW\Http\Middlewares\AccessLog; +use SwooleTW\Http\Middleware\AccessLog; use SwooleTW\Http\Server\Facades\Server; use Illuminate\Contracts\Container\Container; use Symfony\Component\Console\Output\ConsoleOutput; diff --git a/src/HttpServiceProvider.php b/src/HttpServiceProvider.php index be175be1..36f5d688 100644 --- a/src/HttpServiceProvider.php +++ b/src/HttpServiceProvider.php @@ -8,7 +8,7 @@ use Illuminate\Contracts\Http\Kernel; use Swoole\Http\Server as HttpServer; use Illuminate\Support\ServiceProvider; -use SwooleTW\Http\Middlewares\AccessLog; +use SwooleTW\Http\Middleware\AccessLog; use SwooleTW\Http\Server\Facades\Server; use Illuminate\Database\DatabaseManager; use SwooleTW\Http\Coroutine\MySqlConnection; diff --git a/src/Middlewares/AccessLog.php b/src/Middleware/AccessLog.php similarity index 86% rename from src/Middlewares/AccessLog.php rename to src/Middleware/AccessLog.php index 5cc0a4fa..2041b8cf 100644 --- a/src/Middlewares/AccessLog.php +++ b/src/Middleware/AccessLog.php @@ -1,11 +1,11 @@ andReturnSelf(); $request = m::mock(Request::class); - $middlewares = ['foo', 'bar']; + $middleware = ['foo', 'bar']; $pipeline = m::mock(Pipeline::class); $pipeline->shouldReceive('send') ->with($request) ->once() ->andReturnSelf(); $pipeline->shouldReceive('through') - ->with($middlewares) + ->with($middleware) ->once() ->andReturnSelf(); $pipeline->shouldReceive('then') @@ -284,7 +284,7 @@ public function testPipeline() ->andReturn($request); $websocket = $this->getWebsocket(null, $pipeline); - $websocket->middleware($middlewares); + $websocket->middleware($middleware); $websocket->on('connect', function () { return 'connect'; }); From 5deb0e835b873492c6c264cc896ef80b2da334d9 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 13 Jan 2019 19:20:20 +0800 Subject: [PATCH 043/161] fix ExceptionHandler for rendering throwable exception --- src/Server/Manager.php | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 90e43d66..1b276b04 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -222,7 +222,12 @@ public function onRequest($swooleRequest, $swooleResponse) Response::make($illuminateResponse, $swooleResponse)->send(); } catch (Throwable $e) { try { - $exceptionResponse = $this->app->make(ExceptionHandler::class)->render(null, $e); + $exceptionResponse = $this->app + ->make(ExceptionHandler::class) + ->render( + $illuminateRequest, + $this->normalizeException($e) + ); Response::make($exceptionResponse, $swooleResponse)->send(); } catch (Throwable $e) { $this->logServerError($e); @@ -422,11 +427,25 @@ protected function isInTesting() * @param \Throwable|\Exception $e */ public function logServerError(Throwable $e) + { + $this->container + ->make(ExceptionHandler::class) + ->report( + $this->normalizeException($e) + ); + } + + /** + * Normalize a throwable/exception to exception. + * + * @param \Throwable|\Exception $e + */ + protected function normalizeException(Throwable $e) { if (! $e instanceof Exception) { $e = new FatalThrowableError($e); } - $this->container->make(ExceptionHandler::class)->report($e); + return $e; } } From 5477c9a0e1b2b50bdda3c01b8603d3a7928ffeaf Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 13 Jan 2019 19:42:50 +0800 Subject: [PATCH 044/161] refactor code in onTask --- src/Concerns/InteractsWithWebsocket.php | 18 +++++++++++++ src/Server/Manager.php | 36 +++++++++++++++---------- src/Websocket/Push.php | 2 +- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/Concerns/InteractsWithWebsocket.php b/src/Concerns/InteractsWithWebsocket.php index 90f202e4..f0193fc0 100644 --- a/src/Concerns/InteractsWithWebsocket.php +++ b/src/Concerns/InteractsWithWebsocket.php @@ -362,4 +362,22 @@ public function normalizePushData(array $data) return [$opcode, $sender, $fds, $broadcast, $assigned, $event, $message]; } + + /** + * Indicates if the payload is websocket push. + * + * @param mixed $payload + * + * @return boolean + */ + protected function isWebsocketPushPayload($payload): bool + { + if (! is_array($payload)) { + return false; + } + + return $this->isServerWebsocket + && array_key_exists('action', $payload) + && $payload['action'] === Websocket::PUSH_ACTION; + } } diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 1b276b04..fd5a4061 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -263,21 +263,11 @@ public function onTask($server, $taskId, $srcWorkerId, $data) try { // push websocket message - if (is_array($data)) { - if ($this->isServerWebsocket - && array_key_exists('action', $data) - && $data['action'] === Websocket::PUSH_ACTION) { - $this->pushMessage($server, $data['data'] ?? []); - } + if ($this->isWebsocketPushPayload($data)) { + $this->pushMessage($server, $data['data'] ?? []); // push async task to queue - } else { - if (is_string($data)) { - $decoded = \json_decode($data, true); - - if (JSON_ERROR_NONE === \json_last_error() && isset($decoded['job'])) { - (new SwooleTaskJob($this->container, $server, $data, $taskId, $srcWorkerId))->fire(); - } - } + } elseif ($this->isAsyncTaskPayload($data)) { + (new SwooleTaskJob($this->container, $server, $data, $taskId, $srcWorkerId))->fire(); } } catch (Throwable $e) { $this->logServerError($e); @@ -448,4 +438,22 @@ protected function normalizeException(Throwable $e) return $e; } + + /** + * Indicates if the payload is async task. + * + * @param mixed $payload + * + * @return boolean + */ + protected function isAsyncTaskPayload($payload): bool + { + $data = json_decode($payload, true); + + if (JSON_ERROR_NONE !== json_last_error()) { + return false; + } + + return isset($data['job']); + } } diff --git a/src/Websocket/Push.php b/src/Websocket/Push.php index 50323fc8..6d9c27ab 100644 --- a/src/Websocket/Push.php +++ b/src/Websocket/Push.php @@ -141,7 +141,7 @@ public function mergeDescriptor(array $descriptors): void */ public function hasDescriptor(int $descriptor): bool { - return \in_array($descriptor, $this->descriptors, true); + return in_array($descriptor, $this->descriptors, true); } /** From d036c18ffcafac02da9e5ee29fd803a47cf59f76 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 13 Jan 2019 19:51:11 +0800 Subject: [PATCH 045/161] set default of access_log to false --- config/swoole_http.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/swoole_http.php b/config/swoole_http.php index 6825c532..f73a2c59 100644 --- a/config/swoole_http.php +++ b/config/swoole_http.php @@ -15,7 +15,7 @@ 'public_path' => base_path('public'), // Determine if to use swoole to respond request for static files 'handle_static_files' => env('SWOOLE_HANDLE_STATIC', true), - 'access_log' => env('SWOOLE_HTTP_ACCESS_LOG', true), + 'access_log' => env('SWOOLE_HTTP_ACCESS_LOG', false), // You must add --enable-openssl while compiling Swoole // Put `SWOOLE_SOCK_TCP | SWOOLE_SSL` if you want to enable SSL 'socket_type' => SWOOLE_SOCK_TCP, From b40fbb8728e6728281768022fac3c0e8c723b28c Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 13 Jan 2019 20:12:27 +0800 Subject: [PATCH 046/161] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2c9fbbc7..ddaeae45 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This package provides a high performance HTTP server to speed up your Laravel/Lu | PHP | Laravel | Lumen | Swoole | |:-------:|:-------:|:-----:|:-------:| -| >=7.1 | ~5.3 | ~5.1 | >=4.0.0 | +| >=7.1 | ~5.3 | ~5.3 | >=4.0.0 | ## Features From 391e168e1be6e6ed5e1ebd7d38862ecbe6a1c64e Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 13 Jan 2019 20:46:21 +0800 Subject: [PATCH 047/161] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ddaeae45..2b8206a1 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This package provides a high performance HTTP server to speed up your Laravel/Lu | PHP | Laravel | Lumen | Swoole | |:-------:|:-------:|:-----:|:-------:| -| >=7.1 | ~5.3 | ~5.3 | >=4.0.0 | +| >=7.2 | ~5.3 | ~5.3 | >=4.0.0 | ## Features From b65df7080999a8b578c8cc7709164571bc6de81d Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 13 Jan 2019 21:33:45 +0800 Subject: [PATCH 048/161] add support for Lumen 5.7 --- src/Concerns/WithApplication.php | 32 ++++++-------------------------- tests/Server/ManagerTest.php | 6 +----- tests/fixtures/bootstrap/app.php | 22 +++------------------- 3 files changed, 10 insertions(+), 50 deletions(-) diff --git a/src/Concerns/WithApplication.php b/src/Concerns/WithApplication.php index 6ead455f..63f0cdcd 100644 --- a/src/Concerns/WithApplication.php +++ b/src/Concerns/WithApplication.php @@ -24,15 +24,17 @@ trait WithApplication /** * Bootstrap framework. - * - * @throws \ReflectionException */ protected function bootstrap() { if ($this->framework === 'laravel') { - $bootstrappers = $this->getBootstrappers(); - $this->app->bootstrapWith($bootstrappers); + $this->app->bootstrap(); } else { + // for Lumen 5.7 + // https://github.com/laravel/lumen-framework/commit/42cbc998375718b1a8a11883e033617024e57260#diff-c9248b3167fc44af085b81db2e292837 + if (method_exists($this->app, 'boot')) { + $this->app->boot(); + } if (is_null(Facade::getFacadeApplication())) { $this->app->withFacades(); } @@ -75,28 +77,6 @@ public function setApplication(Container $app) $this->app = $app; } - /** - * Get bootstrappers. - * - * @return array - * @throws \ReflectionException - */ - protected function getBootstrappers() - { - $kernel = $this->getApplication()->make(Kernel::class); - - $reflection = new \ReflectionObject($kernel); - - $bootstrappersMethod = $reflection->getMethod('bootstrappers'); - $bootstrappersMethod->setAccessible(true); - - $bootstrappers = $bootstrappersMethod->invoke($kernel); - - array_splice($bootstrappers, -2, 0, ['Illuminate\Foundation\Bootstrap\SetRequestForConsole']); - - return $bootstrappers; - } - /** * Set framework. * diff --git a/tests/Server/ManagerTest.php b/tests/Server/ManagerTest.php index fab6ab3f..a667003b 100644 --- a/tests/Server/ManagerTest.php +++ b/tests/Server/ManagerTest.php @@ -155,9 +155,7 @@ public function testOnWorkerStart() public function testLoadApplication() { $server = $this->getServer(); - $this->getManager(); - - $container = $this->getContainer($this->getServer(), $this->getConfig()); + $container = $this->getContainer($server, $this->getConfig()); $container->singleton('events', function () { return $this->getEvent('swoole.workerStart'); }); @@ -165,8 +163,6 @@ public function testLoadApplication() $path = __DIR__ . '/../fixtures'; $manager = $this->getManager($container, $framework = 'laravel', $path); $manager->onWorkerStart($server); - - $manager->getApplication(); } public function testOnTaskWorkerStart() diff --git a/tests/fixtures/bootstrap/app.php b/tests/fixtures/bootstrap/app.php index ed346bb1..aafbe347 100644 --- a/tests/fixtures/bootstrap/app.php +++ b/tests/fixtures/bootstrap/app.php @@ -1,19 +1,11 @@ shouldReceive('make') - ->with(Kernel::class) - ->once() - ->andReturn($kernel); -$app->shouldReceive('bootstrapWith') - ->once() - ->andReturn($kernel); +$app->shouldReceive('bootstrap') + ->once(); $app->shouldReceive('offsetExists') ->with('foo') ->once() @@ -25,11 +17,3 @@ $app->shouldReceive('alias'); return $app; - -class TestKernel -{ - public function bootstrappers() - { - return []; - } -} \ No newline at end of file From 78327372aa75da559bc4715d4226ea6c193fdaf6 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Mon, 14 Jan 2019 09:52:07 +0800 Subject: [PATCH 049/161] hot fix for laravel's bootstrap in v2.6.0 --- src/Concerns/WithApplication.php | 23 ++++++++++++++++++++++- tests/fixtures/bootstrap/app.php | 20 ++++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/Concerns/WithApplication.php b/src/Concerns/WithApplication.php index 63f0cdcd..a7e28906 100644 --- a/src/Concerns/WithApplication.php +++ b/src/Concerns/WithApplication.php @@ -28,7 +28,8 @@ trait WithApplication protected function bootstrap() { if ($this->framework === 'laravel') { - $this->app->bootstrap(); + $bootstrappers = $this->getBootstrappers(); + $this->app->bootstrapWith($bootstrappers); } else { // for Lumen 5.7 // https://github.com/laravel/lumen-framework/commit/42cbc998375718b1a8a11883e033617024e57260#diff-c9248b3167fc44af085b81db2e292837 @@ -137,4 +138,24 @@ protected function preResolveInstances() } } } + + /** + * Get bootstrappers. + * + * @return array + * @throws \ReflectionException + */ + protected function getBootstrappers() + { + $kernel = $this->getApplication()->make(Kernel::class); + + $reflection = new \ReflectionObject($kernel); + $bootstrappersMethod = $reflection->getMethod('bootstrappers'); + $bootstrappersMethod->setAccessible(true); + $bootstrappers = $bootstrappersMethod->invoke($kernel); + + array_splice($bootstrappers, -2, 0, ['Illuminate\Foundation\Bootstrap\SetRequestForConsole']); + + return $bootstrappers; + } } diff --git a/tests/fixtures/bootstrap/app.php b/tests/fixtures/bootstrap/app.php index aafbe347..79e6824b 100644 --- a/tests/fixtures/bootstrap/app.php +++ b/tests/fixtures/bootstrap/app.php @@ -1,11 +1,19 @@ shouldReceive('bootstrap') - ->once(); + +$app->shouldReceive('make') + ->with(Kernel::class) + ->once() + ->andReturn($kernel); +$app->shouldReceive('bootstrapWith') + ->once() + ->andReturn($kernel); $app->shouldReceive('offsetExists') ->with('foo') ->once() @@ -17,3 +25,11 @@ $app->shouldReceive('alias'); return $app; + +class TestKernel +{ + public function bootstrappers() + { + return []; + } +} From 090e8d788ddabd9a43bc6e0334706bc71142871a Mon Sep 17 00:00:00 2001 From: Karl Li Date: Fri, 18 Jan 2019 17:13:22 +0800 Subject: [PATCH 050/161] using MimeType to detect mimetype of file --- src/Transformers/Request.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Transformers/Request.php b/src/Transformers/Request.php index eefd2bdf..8f65f886 100644 --- a/src/Transformers/Request.php +++ b/src/Transformers/Request.php @@ -4,6 +4,7 @@ use Illuminate\Http\Request as IlluminateRequest; use Illuminate\Http\Response as IlluminateResponse; +use Illuminate\Http\Testing\MimeType; use Swoole\Http\Request as SwooleRequest; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request as SymfonyRequest; @@ -191,7 +192,7 @@ public static function handleStatic($swooleRequest, $swooleResponse, string $pub return false; } - $contentType = mime_content_type($fileName); + $contentType = MimeType::from($fileName); $swooleResponse->status(IlluminateResponse::HTTP_OK); $swooleResponse->header('Content-Type', static::EXTENSION_MIMES[$contentType] ?? $contentType); From 161649020a9075056ad8dc6bcc387f5cd56c79b5 Mon Sep 17 00:00:00 2001 From: Karl Li Date: Fri, 18 Jan 2019 17:17:49 +0800 Subject: [PATCH 051/161] update request test --- tests/Transformers/RequestTest.php | 43 ++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/tests/Transformers/RequestTest.php b/tests/Transformers/RequestTest.php index 2eecd190..1f8364fc 100644 --- a/tests/Transformers/RequestTest.php +++ b/tests/Transformers/RequestTest.php @@ -3,6 +3,7 @@ namespace SwooleTW\Http\Tests\Transformers; use Illuminate\Http\Request as IlluminateRequest; +use Illuminate\Http\Testing\MimeType; use Mockery as m; use Swoole\Http\Request as SwooleRequest; use SwooleTW\Http\Tests\TestCase; @@ -38,19 +39,51 @@ public function testHandleStatic() return 1; }); - $mimeContentType = false; - $this->mockMethod('mime_content_type', function () use (&$mimeContentType) { - $mimeContentType = true; + m::mock(MimeType::class)->shouldReceive('from') + ->withAnyArgs() + ->andReturn('foo'); - return 'foo'; + $response = m::mock('response'); + $response->shouldReceive('status') + ->with(200) + ->once(); + $response->shouldReceive('header') + ->with('Content-Type', 'application/octet-stream') + ->once(); + $response->shouldReceive('sendfile') + ->with('/foo.bar') + ->once(); + + Request::handleStatic(new SwooleRequestStub, $response, '/'); + + $this->assertTrue($isFile); + $this->assertTrue($fileSize); + } + + public function testHandleStaticCss() + { + $isFile = false; + $this->mockMethod('is_file', function () use (&$isFile) { + return $isFile = true; + }); + + $fileSize = false; + $this->mockMethod('filesize', function () use (&$fileSize) { + $fileSize = true; + + return 1; }); + m::mock(MimeType::class)->shouldReceive('from') + ->withAnyArgs() + ->andReturn('text/css'); + $response = m::mock('response'); $response->shouldReceive('status') ->with(200) ->once(); $response->shouldReceive('header') - ->with('Content-Type', 'foo') + ->with('Content-Type', 'application/octet-stream') ->once(); $response->shouldReceive('sendfile') ->with('/foo.bar') From b0a42a28d8834da617312906ffbf6f37843003f6 Mon Sep 17 00:00:00 2001 From: Karl Li Date: Fri, 18 Jan 2019 19:00:52 +0800 Subject: [PATCH 052/161] using MimeType if laravel/lumen version great then 5.3 --- src/Transformers/Request.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Transformers/Request.php b/src/Transformers/Request.php index 8f65f886..e8c61b3b 100644 --- a/src/Transformers/Request.php +++ b/src/Transformers/Request.php @@ -6,6 +6,7 @@ use Illuminate\Http\Response as IlluminateResponse; use Illuminate\Http\Testing\MimeType; use Swoole\Http\Request as SwooleRequest; +use SwooleTW\Http\Helpers\FW; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request as SymfonyRequest; @@ -192,7 +193,11 @@ public static function handleStatic($swooleRequest, $swooleResponse, string $pub return false; } - $contentType = MimeType::from($fileName); + if (version_compare(FW::version(), '5.3', '>')) { + $contentType = MimeType::get($extension); + } else { + $contentType = static::EXTENSION_MIMES[$extension] ?? mime_content_type($fileName); + } $swooleResponse->status(IlluminateResponse::HTTP_OK); $swooleResponse->header('Content-Type', static::EXTENSION_MIMES[$contentType] ?? $contentType); From 273f54fc719088eff815bb78ddf22116ec79d435 Mon Sep 17 00:00:00 2001 From: Karl Li Date: Fri, 18 Jan 2019 19:00:56 +0800 Subject: [PATCH 053/161] update test --- tests/Transformers/RequestTest.php | 42 +++--------------------------- 1 file changed, 3 insertions(+), 39 deletions(-) diff --git a/tests/Transformers/RequestTest.php b/tests/Transformers/RequestTest.php index 1f8364fc..c084d798 100644 --- a/tests/Transformers/RequestTest.php +++ b/tests/Transformers/RequestTest.php @@ -3,7 +3,6 @@ namespace SwooleTW\Http\Tests\Transformers; use Illuminate\Http\Request as IlluminateRequest; -use Illuminate\Http\Testing\MimeType; use Mockery as m; use Swoole\Http\Request as SwooleRequest; use SwooleTW\Http\Tests\TestCase; @@ -39,51 +38,16 @@ public function testHandleStatic() return 1; }); - m::mock(MimeType::class)->shouldReceive('from') - ->withAnyArgs() - ->andReturn('foo'); - - $response = m::mock('response'); - $response->shouldReceive('status') - ->with(200) - ->once(); - $response->shouldReceive('header') - ->with('Content-Type', 'application/octet-stream') - ->once(); - $response->shouldReceive('sendfile') - ->with('/foo.bar') - ->once(); - - Request::handleStatic(new SwooleRequestStub, $response, '/'); - - $this->assertTrue($isFile); - $this->assertTrue($fileSize); - } - - public function testHandleStaticCss() - { - $isFile = false; - $this->mockMethod('is_file', function () use (&$isFile) { - return $isFile = true; - }); - - $fileSize = false; - $this->mockMethod('filesize', function () use (&$fileSize) { - $fileSize = true; - - return 1; + $this->mockMethod('pathinfo', function () { + return 'css'; }); - m::mock(MimeType::class)->shouldReceive('from') - ->withAnyArgs() - ->andReturn('text/css'); - $response = m::mock('response'); $response->shouldReceive('status') ->with(200) ->once(); $response->shouldReceive('header') - ->with('Content-Type', 'application/octet-stream') + ->with('Content-Type', 'text/css') ->once(); $response->shouldReceive('sendfile') ->with('/foo.bar') From 433474b19dfd6570a5742d3c84d0153285b1bdcf Mon Sep 17 00:00:00 2001 From: Karl Li Date: Thu, 24 Jan 2019 15:54:06 +0800 Subject: [PATCH 054/161] get extionsion without query parameters --- src/Transformers/Request.php | 2 +- tests/Transformers/RequestTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Transformers/Request.php b/src/Transformers/Request.php index e8c61b3b..e48558ae 100644 --- a/src/Transformers/Request.php +++ b/src/Transformers/Request.php @@ -182,7 +182,7 @@ protected static function transformServerParameters(array $server, array $header public static function handleStatic($swooleRequest, $swooleResponse, string $publicPath) { $uri = $swooleRequest->server['request_uri'] ?? ''; - $extension = pathinfo($uri, PATHINFO_EXTENSION); + $extension = strtok(pathinfo($uri, PATHINFO_EXTENSION), '?'); $fileName = $publicPath . $uri; if ($extension && in_array($extension, static::EXTENSION_BLACKLIST)) { diff --git a/tests/Transformers/RequestTest.php b/tests/Transformers/RequestTest.php index c084d798..82adf818 100644 --- a/tests/Transformers/RequestTest.php +++ b/tests/Transformers/RequestTest.php @@ -39,7 +39,7 @@ public function testHandleStatic() }); $this->mockMethod('pathinfo', function () { - return 'css'; + return 'css?id=bfaf14972de9d89ae8fc'; }); $response = m::mock('response'); From 6e93bee82f42ce4d3a1662cbf702a79cf054be10 Mon Sep 17 00:00:00 2001 From: Karl Li Date: Thu, 24 Jan 2019 15:55:35 +0800 Subject: [PATCH 055/161] using MimeType if laravel version is greater than 5.4 --- src/Transformers/Request.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Transformers/Request.php b/src/Transformers/Request.php index e48558ae..4255a235 100644 --- a/src/Transformers/Request.php +++ b/src/Transformers/Request.php @@ -193,14 +193,14 @@ public static function handleStatic($swooleRequest, $swooleResponse, string $pub return false; } - if (version_compare(FW::version(), '5.3', '>')) { + if (version_compare(FW::version(), '5.4', '>')) { $contentType = MimeType::get($extension); } else { $contentType = static::EXTENSION_MIMES[$extension] ?? mime_content_type($fileName); } $swooleResponse->status(IlluminateResponse::HTTP_OK); - $swooleResponse->header('Content-Type', static::EXTENSION_MIMES[$contentType] ?? $contentType); + $swooleResponse->header('Content-Type', $contentType); $swooleResponse->sendfile($fileName); return true; From 6e93c57682b7bbe9ba138fd10c851595688f4149 Mon Sep 17 00:00:00 2001 From: Karl Li Date: Mon, 28 Jan 2019 10:27:22 +0800 Subject: [PATCH 056/161] copy MimeType from Illuminate --- src/Helpers/MimeType.php | 821 +++++++++++++++++++++++++++++++++ src/Transformers/Request.php | 10 +- tests/Helpers/MimeTypeTest.php | 25 + 3 files changed, 848 insertions(+), 8 deletions(-) create mode 100644 src/Helpers/MimeType.php create mode 100644 tests/Helpers/MimeTypeTest.php diff --git a/src/Helpers/MimeType.php b/src/Helpers/MimeType.php new file mode 100644 index 00000000..5edab5cf --- /dev/null +++ b/src/Helpers/MimeType.php @@ -0,0 +1,821 @@ + 'application/andrew-inset', + 'aw' => 'application/applixware', + 'atom' => 'application/atom+xml', + 'atomcat' => 'application/atomcat+xml', + 'atomsvc' => 'application/atomsvc+xml', + 'ccxml' => 'application/ccxml+xml', + 'cdmia' => 'application/cdmi-capability', + 'cdmic' => 'application/cdmi-container', + 'cdmid' => 'application/cdmi-domain', + 'cdmio' => 'application/cdmi-object', + 'cdmiq' => 'application/cdmi-queue', + 'cu' => 'application/cu-seeme', + 'davmount' => 'application/davmount+xml', + 'dbk' => 'application/docbook+xml', + 'dssc' => 'application/dssc+der', + 'xdssc' => 'application/dssc+xml', + 'ecma' => 'application/ecmascript', + 'emma' => 'application/emma+xml', + 'epub' => 'application/epub+zip', + 'exi' => 'application/exi', + 'pfr' => 'application/font-tdpfr', + 'gml' => 'application/gml+xml', + 'gpx' => 'application/gpx+xml', + 'gxf' => 'application/gxf', + 'stk' => 'application/hyperstudio', + 'ink' => 'application/inkml+xml', + 'ipfix' => 'application/ipfix', + 'jar' => 'application/java-archive', + 'ser' => 'application/java-serialized-object', + 'class' => 'application/java-vm', + 'js' => 'application/javascript', + 'json' => 'application/json', + 'jsonml' => 'application/jsonml+json', + 'lostxml' => 'application/lost+xml', + 'hqx' => 'application/mac-binhex40', + 'cpt' => 'application/mac-compactpro', + 'mads' => 'application/mads+xml', + 'mrc' => 'application/marc', + 'mrcx' => 'application/marcxml+xml', + 'ma' => 'application/mathematica', + 'mathml' => 'application/mathml+xml', + 'mbox' => 'application/mbox', + 'mscml' => 'application/mediaservercontrol+xml', + 'metalink' => 'application/metalink+xml', + 'meta4' => 'application/metalink4+xml', + 'mets' => 'application/mets+xml', + 'mods' => 'application/mods+xml', + 'm21' => 'application/mp21', + 'mp4s' => 'application/mp4', + 'doc' => 'application/msword', + 'mxf' => 'application/mxf', + 'bin' => 'application/octet-stream', + 'oda' => 'application/oda', + 'opf' => 'application/oebps-package+xml', + 'ogx' => 'application/ogg', + 'omdoc' => 'application/omdoc+xml', + 'onetoc' => 'application/onenote', + 'oxps' => 'application/oxps', + 'xer' => 'application/patch-ops-error+xml', + 'pdf' => 'application/pdf', + 'pgp' => 'application/pgp-encrypted', + 'asc' => 'application/pgp-signature', + 'prf' => 'application/pics-rules', + 'p10' => 'application/pkcs10', + 'p7m' => 'application/pkcs7-mime', + 'p7s' => 'application/pkcs7-signature', + 'p8' => 'application/pkcs8', + 'ac' => 'application/pkix-attr-cert', + 'cer' => 'application/pkix-cert', + 'crl' => 'application/pkix-crl', + 'pkipath' => 'application/pkix-pkipath', + 'pki' => 'application/pkixcmp', + 'pls' => 'application/pls+xml', + 'ai' => 'application/postscript', + 'cww' => 'application/prs.cww', + 'pskcxml' => 'application/pskc+xml', + 'rdf' => 'application/rdf+xml', + 'rif' => 'application/reginfo+xml', + 'rnc' => 'application/relax-ng-compact-syntax', + 'rl' => 'application/resource-lists+xml', + 'rld' => 'application/resource-lists-diff+xml', + 'rs' => 'application/rls-services+xml', + 'gbr' => 'application/rpki-ghostbusters', + 'mft' => 'application/rpki-manifest', + 'roa' => 'application/rpki-roa', + 'rsd' => 'application/rsd+xml', + 'rss' => 'application/rss+xml', + 'sbml' => 'application/sbml+xml', + 'scq' => 'application/scvp-cv-request', + 'scs' => 'application/scvp-cv-response', + 'spq' => 'application/scvp-vp-request', + 'spp' => 'application/scvp-vp-response', + 'sdp' => 'application/sdp', + 'setpay' => 'application/set-payment-initiation', + 'setreg' => 'application/set-registration-initiation', + 'shf' => 'application/shf+xml', + 'smi' => 'application/smil+xml', + 'rq' => 'application/sparql-query', + 'srx' => 'application/sparql-results+xml', + 'gram' => 'application/srgs', + 'grxml' => 'application/srgs+xml', + 'sru' => 'application/sru+xml', + 'ssdl' => 'application/ssdl+xml', + 'ssml' => 'application/ssml+xml', + 'tei' => 'application/tei+xml', + 'tfi' => 'application/thraud+xml', + 'tsd' => 'application/timestamped-data', + 'plb' => 'application/vnd.3gpp.pic-bw-large', + 'psb' => 'application/vnd.3gpp.pic-bw-small', + 'pvb' => 'application/vnd.3gpp.pic-bw-var', + 'tcap' => 'application/vnd.3gpp2.tcap', + 'pwn' => 'application/vnd.3m.post-it-notes', + 'aso' => 'application/vnd.accpac.simply.aso', + 'imp' => 'application/vnd.accpac.simply.imp', + 'acu' => 'application/vnd.acucobol', + 'atc' => 'application/vnd.acucorp', + 'air' => 'application/vnd.adobe.air-application-installer-package+zip', + 'fcdt' => 'application/vnd.adobe.formscentral.fcdt', + 'fxp' => 'application/vnd.adobe.fxp', + 'xdp' => 'application/vnd.adobe.xdp+xml', + 'xfdf' => 'application/vnd.adobe.xfdf', + 'ahead' => 'application/vnd.ahead.space', + 'azf' => 'application/vnd.airzip.filesecure.azf', + 'azs' => 'application/vnd.airzip.filesecure.azs', + 'azw' => 'application/vnd.amazon.ebook', + 'acc' => 'application/vnd.americandynamics.acc', + 'ami' => 'application/vnd.amiga.ami', + 'apk' => 'application/vnd.android.package-archive', + 'cii' => 'application/vnd.anser-web-certificate-issue-initiation', + 'fti' => 'application/vnd.anser-web-funds-transfer-initiation', + 'atx' => 'application/vnd.antix.game-component', + 'mpkg' => 'application/vnd.apple.installer+xml', + 'm3u8' => 'application/vnd.apple.mpegurl', + 'swi' => 'application/vnd.aristanetworks.swi', + 'iota' => 'application/vnd.astraea-software.iota', + 'aep' => 'application/vnd.audiograph', + 'mpm' => 'application/vnd.blueice.multipass', + 'bmi' => 'application/vnd.bmi', + 'rep' => 'application/vnd.businessobjects', + 'cdxml' => 'application/vnd.chemdraw+xml', + 'mmd' => 'application/vnd.chipnuts.karaoke-mmd', + 'cdy' => 'application/vnd.cinderella', + 'cla' => 'application/vnd.claymore', + 'rp9' => 'application/vnd.cloanto.rp9', + 'c4g' => 'application/vnd.clonk.c4group', + 'c11amc' => 'application/vnd.cluetrust.cartomobile-config', + 'c11amz' => 'application/vnd.cluetrust.cartomobile-config-pkg', + 'csp' => 'application/vnd.commonspace', + 'cdbcmsg' => 'application/vnd.contact.cmsg', + 'cmc' => 'application/vnd.cosmocaller', + 'clkx' => 'application/vnd.crick.clicker', + 'clkk' => 'application/vnd.crick.clicker.keyboard', + 'clkp' => 'application/vnd.crick.clicker.palette', + 'clkt' => 'application/vnd.crick.clicker.template', + 'clkw' => 'application/vnd.crick.clicker.wordbank', + 'wbs' => 'application/vnd.criticaltools.wbs+xml', + 'pml' => 'application/vnd.ctc-posml', + 'ppd' => 'application/vnd.cups-ppd', + 'car' => 'application/vnd.curl.car', + 'pcurl' => 'application/vnd.curl.pcurl', + 'dart' => 'application/vnd.dart', + 'rdz' => 'application/vnd.data-vision.rdz', + 'uvf' => 'application/vnd.dece.data', + 'uvt' => 'application/vnd.dece.ttml+xml', + 'uvx' => 'application/vnd.dece.unspecified', + 'uvz' => 'application/vnd.dece.zip', + 'fe_launch' => 'application/vnd.denovo.fcselayout-link', + 'dna' => 'application/vnd.dna', + 'mlp' => 'application/vnd.dolby.mlp', + 'dpg' => 'application/vnd.dpgraph', + 'dfac' => 'application/vnd.dreamfactory', + 'kpxx' => 'application/vnd.ds-keypoint', + 'ait' => 'application/vnd.dvb.ait', + 'svc' => 'application/vnd.dvb.service', + 'geo' => 'application/vnd.dynageo', + 'mag' => 'application/vnd.ecowin.chart', + 'nml' => 'application/vnd.enliven', + 'esf' => 'application/vnd.epson.esf', + 'msf' => 'application/vnd.epson.msf', + 'qam' => 'application/vnd.epson.quickanime', + 'slt' => 'application/vnd.epson.salt', + 'ssf' => 'application/vnd.epson.ssf', + 'es3' => 'application/vnd.eszigno3+xml', + 'ez2' => 'application/vnd.ezpix-album', + 'ez3' => 'application/vnd.ezpix-package', + 'fdf' => 'application/vnd.fdf', + 'mseed' => 'application/vnd.fdsn.mseed', + 'seed' => 'application/vnd.fdsn.seed', + 'gph' => 'application/vnd.flographit', + 'ftc' => 'application/vnd.fluxtime.clip', + 'fm' => 'application/vnd.framemaker', + 'fnc' => 'application/vnd.frogans.fnc', + 'ltf' => 'application/vnd.frogans.ltf', + 'fsc' => 'application/vnd.fsc.weblaunch', + 'oas' => 'application/vnd.fujitsu.oasys', + 'oa2' => 'application/vnd.fujitsu.oasys2', + 'oa3' => 'application/vnd.fujitsu.oasys3', + 'fg5' => 'application/vnd.fujitsu.oasysgp', + 'bh2' => 'application/vnd.fujitsu.oasysprs', + 'ddd' => 'application/vnd.fujixerox.ddd', + 'xdw' => 'application/vnd.fujixerox.docuworks', + 'xbd' => 'application/vnd.fujixerox.docuworks.binder', + 'fzs' => 'application/vnd.fuzzysheet', + 'txd' => 'application/vnd.genomatix.tuxedo', + 'ggb' => 'application/vnd.geogebra.file', + 'ggt' => 'application/vnd.geogebra.tool', + 'gex' => 'application/vnd.geometry-explorer', + 'gxt' => 'application/vnd.geonext', + 'g2w' => 'application/vnd.geoplan', + 'g3w' => 'application/vnd.geospace', + 'gmx' => 'application/vnd.gmx', + 'kml' => 'application/vnd.google-earth.kml+xml', + 'kmz' => 'application/vnd.google-earth.kmz', + 'gqf' => 'application/vnd.grafeq', + 'gac' => 'application/vnd.groove-account', + 'ghf' => 'application/vnd.groove-help', + 'gim' => 'application/vnd.groove-identity-message', + 'grv' => 'application/vnd.groove-injector', + 'gtm' => 'application/vnd.groove-tool-message', + 'tpl' => 'application/vnd.groove-tool-template', + 'vcg' => 'application/vnd.groove-vcard', + 'hal' => 'application/vnd.hal+xml', + 'zmm' => 'application/vnd.handheld-entertainment+xml', + 'hbci' => 'application/vnd.hbci', + 'les' => 'application/vnd.hhe.lesson-player', + 'hpgl' => 'application/vnd.hp-hpgl', + 'hpid' => 'application/vnd.hp-hpid', + 'hps' => 'application/vnd.hp-hps', + 'jlt' => 'application/vnd.hp-jlyt', + 'pcl' => 'application/vnd.hp-pcl', + 'pclxl' => 'application/vnd.hp-pclxl', + 'sfd-hdstx' => 'application/vnd.hydrostatix.sof-data', + 'mpy' => 'application/vnd.ibm.minipay', + 'afp' => 'application/vnd.ibm.modcap', + 'irm' => 'application/vnd.ibm.rights-management', + 'sc' => 'application/vnd.ibm.secure-container', + 'icc' => 'application/vnd.iccprofile', + 'igl' => 'application/vnd.igloader', + 'ivp' => 'application/vnd.immervision-ivp', + 'ivu' => 'application/vnd.immervision-ivu', + 'igm' => 'application/vnd.insors.igm', + 'xpw' => 'application/vnd.intercon.formnet', + 'i2g' => 'application/vnd.intergeo', + 'qbo' => 'application/vnd.intu.qbo', + 'qfx' => 'application/vnd.intu.qfx', + 'rcprofile' => 'application/vnd.ipunplugged.rcprofile', + 'irp' => 'application/vnd.irepository.package+xml', + 'xpr' => 'application/vnd.is-xpr', + 'fcs' => 'application/vnd.isac.fcs', + 'jam' => 'application/vnd.jam', + 'rms' => 'application/vnd.jcp.javame.midlet-rms', + 'jisp' => 'application/vnd.jisp', + 'joda' => 'application/vnd.joost.joda-archive', + 'ktz' => 'application/vnd.kahootz', + 'karbon' => 'application/vnd.kde.karbon', + 'chrt' => 'application/vnd.kde.kchart', + 'kfo' => 'application/vnd.kde.kformula', + 'flw' => 'application/vnd.kde.kivio', + 'kon' => 'application/vnd.kde.kontour', + 'kpr' => 'application/vnd.kde.kpresenter', + 'ksp' => 'application/vnd.kde.kspread', + 'kwd' => 'application/vnd.kde.kword', + 'htke' => 'application/vnd.kenameaapp', + 'kia' => 'application/vnd.kidspiration', + 'kne' => 'application/vnd.kinar', + 'skp' => 'application/vnd.koan', + 'sse' => 'application/vnd.kodak-descriptor', + 'lasxml' => 'application/vnd.las.las+xml', + 'lbd' => 'application/vnd.llamagraphics.life-balance.desktop', + 'lbe' => 'application/vnd.llamagraphics.life-balance.exchange+xml', + '123' => 'application/vnd.lotus-1-2-3', + 'apr' => 'application/vnd.lotus-approach', + 'pre' => 'application/vnd.lotus-freelance', + 'nsf' => 'application/vnd.lotus-notes', + 'org' => 'application/vnd.lotus-organizer', + 'scm' => 'application/vnd.lotus-screencam', + 'lwp' => 'application/vnd.lotus-wordpro', + 'portpkg' => 'application/vnd.macports.portpkg', + 'mcd' => 'application/vnd.mcd', + 'mc1' => 'application/vnd.medcalcdata', + 'cdkey' => 'application/vnd.mediastation.cdkey', + 'mwf' => 'application/vnd.mfer', + 'mfm' => 'application/vnd.mfmp', + 'flo' => 'application/vnd.micrografx.flo', + 'igx' => 'application/vnd.micrografx.igx', + 'mif' => 'application/vnd.mif', + 'daf' => 'application/vnd.mobius.daf', + 'dis' => 'application/vnd.mobius.dis', + 'mbk' => 'application/vnd.mobius.mbk', + 'mqy' => 'application/vnd.mobius.mqy', + 'msl' => 'application/vnd.mobius.msl', + 'plc' => 'application/vnd.mobius.plc', + 'txf' => 'application/vnd.mobius.txf', + 'mpn' => 'application/vnd.mophun.application', + 'mpc' => 'application/vnd.mophun.certificate', + 'xul' => 'application/vnd.mozilla.xul+xml', + 'cil' => 'application/vnd.ms-artgalry', + 'cab' => 'application/vnd.ms-cab-compressed', + 'xls' => 'application/vnd.ms-excel', + 'xlam' => 'application/vnd.ms-excel.addin.macroenabled.12', + 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroenabled.12', + 'xlsm' => 'application/vnd.ms-excel.sheet.macroenabled.12', + 'xltm' => 'application/vnd.ms-excel.template.macroenabled.12', + 'eot' => 'application/vnd.ms-fontobject', + 'chm' => 'application/vnd.ms-htmlhelp', + 'ims' => 'application/vnd.ms-ims', + 'lrm' => 'application/vnd.ms-lrm', + 'thmx' => 'application/vnd.ms-officetheme', + 'cat' => 'application/vnd.ms-pki.seccat', + 'stl' => 'application/vnd.ms-pki.stl', + 'ppt' => 'application/vnd.ms-powerpoint', + 'ppam' => 'application/vnd.ms-powerpoint.addin.macroenabled.12', + 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroenabled.12', + 'sldm' => 'application/vnd.ms-powerpoint.slide.macroenabled.12', + 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroenabled.12', + 'potm' => 'application/vnd.ms-powerpoint.template.macroenabled.12', + 'mpp' => 'application/vnd.ms-project', + 'docm' => 'application/vnd.ms-word.document.macroenabled.12', + 'dotm' => 'application/vnd.ms-word.template.macroenabled.12', + 'wps' => 'application/vnd.ms-works', + 'wpl' => 'application/vnd.ms-wpl', + 'xps' => 'application/vnd.ms-xpsdocument', + 'mseq' => 'application/vnd.mseq', + 'mus' => 'application/vnd.musician', + 'msty' => 'application/vnd.muvee.style', + 'taglet' => 'application/vnd.mynfc', + 'nlu' => 'application/vnd.neurolanguage.nlu', + 'ntf' => 'application/vnd.nitf', + 'nnd' => 'application/vnd.noblenet-directory', + 'nns' => 'application/vnd.noblenet-sealer', + 'nnw' => 'application/vnd.noblenet-web', + 'ngdat' => 'application/vnd.nokia.n-gage.data', + 'n-gage' => 'application/vnd.nokia.n-gage.symbian.install', + 'rpst' => 'application/vnd.nokia.radio-preset', + 'rpss' => 'application/vnd.nokia.radio-presets', + 'edm' => 'application/vnd.novadigm.edm', + 'edx' => 'application/vnd.novadigm.edx', + 'ext' => 'application/vnd.novadigm.ext', + 'odc' => 'application/vnd.oasis.opendocument.chart', + 'otc' => 'application/vnd.oasis.opendocument.chart-template', + 'odb' => 'application/vnd.oasis.opendocument.database', + 'odf' => 'application/vnd.oasis.opendocument.formula', + 'odft' => 'application/vnd.oasis.opendocument.formula-template', + 'odg' => 'application/vnd.oasis.opendocument.graphics', + 'otg' => 'application/vnd.oasis.opendocument.graphics-template', + 'odi' => 'application/vnd.oasis.opendocument.image', + 'oti' => 'application/vnd.oasis.opendocument.image-template', + 'odp' => 'application/vnd.oasis.opendocument.presentation', + 'otp' => 'application/vnd.oasis.opendocument.presentation-template', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', + 'odt' => 'application/vnd.oasis.opendocument.text', + 'odm' => 'application/vnd.oasis.opendocument.text-master', + 'ott' => 'application/vnd.oasis.opendocument.text-template', + 'oth' => 'application/vnd.oasis.opendocument.text-web', + 'xo' => 'application/vnd.olpc-sugar', + 'dd2' => 'application/vnd.oma.dd2+xml', + 'oxt' => 'application/vnd.openofficeorg.extension', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', + 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', + 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', + 'mgp' => 'application/vnd.osgeo.mapguide.package', + 'dp' => 'application/vnd.osgi.dp', + 'esa' => 'application/vnd.osgi.subsystem', + 'pdb' => 'application/vnd.palm', + 'paw' => 'application/vnd.pawaafile', + 'str' => 'application/vnd.pg.format', + 'ei6' => 'application/vnd.pg.osasli', + 'efif' => 'application/vnd.picsel', + 'wg' => 'application/vnd.pmi.widget', + 'plf' => 'application/vnd.pocketlearn', + 'pbd' => 'application/vnd.powerbuilder6', + 'box' => 'application/vnd.previewsystems.box', + 'mgz' => 'application/vnd.proteus.magazine', + 'qps' => 'application/vnd.publishare-delta-tree', + 'ptid' => 'application/vnd.pvi.ptid1', + 'qxd' => 'application/vnd.quark.quarkxpress', + 'bed' => 'application/vnd.realvnc.bed', + 'mxl' => 'application/vnd.recordare.musicxml', + 'musicxml' => 'application/vnd.recordare.musicxml+xml', + 'cryptonote' => 'application/vnd.rig.cryptonote', + 'cod' => 'application/vnd.rim.cod', + 'rm' => 'application/vnd.rn-realmedia', + 'rmvb' => 'application/vnd.rn-realmedia-vbr', + 'link66' => 'application/vnd.route66.link66+xml', + 'st' => 'application/vnd.sailingtracker.track', + 'see' => 'application/vnd.seemail', + 'sema' => 'application/vnd.sema', + 'semd' => 'application/vnd.semd', + 'semf' => 'application/vnd.semf', + 'ifm' => 'application/vnd.shana.informed.formdata', + 'itp' => 'application/vnd.shana.informed.formtemplate', + 'iif' => 'application/vnd.shana.informed.interchange', + 'ipk' => 'application/vnd.shana.informed.package', + 'twd' => 'application/vnd.simtech-mindmapper', + 'mmf' => 'application/vnd.smaf', + 'teacher' => 'application/vnd.smart.teacher', + 'sdkm' => 'application/vnd.solent.sdkm+xml', + 'dxp' => 'application/vnd.spotfire.dxp', + 'sfs' => 'application/vnd.spotfire.sfs', + 'sdc' => 'application/vnd.stardivision.calc', + 'sda' => 'application/vnd.stardivision.draw', + 'sdd' => 'application/vnd.stardivision.impress', + 'smf' => 'application/vnd.stardivision.math', + 'sdw' => 'application/vnd.stardivision.writer', + 'sgl' => 'application/vnd.stardivision.writer-global', + 'smzip' => 'application/vnd.stepmania.package', + 'sm' => 'application/vnd.stepmania.stepchart', + 'sxc' => 'application/vnd.sun.xml.calc', + 'stc' => 'application/vnd.sun.xml.calc.template', + 'sxd' => 'application/vnd.sun.xml.draw', + 'std' => 'application/vnd.sun.xml.draw.template', + 'sxi' => 'application/vnd.sun.xml.impress', + 'sti' => 'application/vnd.sun.xml.impress.template', + 'sxm' => 'application/vnd.sun.xml.math', + 'sxw' => 'application/vnd.sun.xml.writer', + 'sxg' => 'application/vnd.sun.xml.writer.global', + 'stw' => 'application/vnd.sun.xml.writer.template', + 'sus' => 'application/vnd.sus-calendar', + 'svd' => 'application/vnd.svd', + 'sis' => 'application/vnd.symbian.install', + 'xsm' => 'application/vnd.syncml+xml', + 'bdm' => 'application/vnd.syncml.dm+wbxml', + 'xdm' => 'application/vnd.syncml.dm+xml', + 'tao' => 'application/vnd.tao.intent-module-archive', + 'pcap' => 'application/vnd.tcpdump.pcap', + 'tmo' => 'application/vnd.tmobile-livetv', + 'tpt' => 'application/vnd.trid.tpt', + 'mxs' => 'application/vnd.triscape.mxs', + 'tra' => 'application/vnd.trueapp', + 'ufd' => 'application/vnd.ufdl', + 'utz' => 'application/vnd.uiq.theme', + 'umj' => 'application/vnd.umajin', + 'unityweb' => 'application/vnd.unity', + 'uoml' => 'application/vnd.uoml+xml', + 'vcx' => 'application/vnd.vcx', + 'vsd' => 'application/vnd.visio', + 'vis' => 'application/vnd.visionary', + 'vsf' => 'application/vnd.vsf', + 'wbxml' => 'application/vnd.wap.wbxml', + 'wmlc' => 'application/vnd.wap.wmlc', + 'wmlsc' => 'application/vnd.wap.wmlscriptc', + 'wtb' => 'application/vnd.webturbo', + 'nbp' => 'application/vnd.wolfram.player', + 'wpd' => 'application/vnd.wordperfect', + 'wqd' => 'application/vnd.wqd', + 'stf' => 'application/vnd.wt.stf', + 'xar' => 'application/vnd.xara', + 'xfdl' => 'application/vnd.xfdl', + 'hvd' => 'application/vnd.yamaha.hv-dic', + 'hvs' => 'application/vnd.yamaha.hv-script', + 'hvp' => 'application/vnd.yamaha.hv-voice', + 'osf' => 'application/vnd.yamaha.openscoreformat', + 'osfpvg' => 'application/vnd.yamaha.openscoreformat.osfpvg+xml', + 'saf' => 'application/vnd.yamaha.smaf-audio', + 'spf' => 'application/vnd.yamaha.smaf-phrase', + 'cmp' => 'application/vnd.yellowriver-custom-menu', + 'zir' => 'application/vnd.zul', + 'zaz' => 'application/vnd.zzazz.deck+xml', + 'vxml' => 'application/voicexml+xml', + 'wgt' => 'application/widget', + 'hlp' => 'application/winhlp', + 'wsdl' => 'application/wsdl+xml', + 'wspolicy' => 'application/wspolicy+xml', + '7z' => 'application/x-7z-compressed', + 'abw' => 'application/x-abiword', + 'ace' => 'application/x-ace-compressed', + 'dmg' => 'application/x-apple-diskimage', + 'aab' => 'application/x-authorware-bin', + 'aam' => 'application/x-authorware-map', + 'aas' => 'application/x-authorware-seg', + 'bcpio' => 'application/x-bcpio', + 'torrent' => 'application/x-bittorrent', + 'blb' => 'application/x-blorb', + 'bz' => 'application/x-bzip', + 'bz2' => 'application/x-bzip2', + 'cbr' => 'application/x-cbr', + 'vcd' => 'application/x-cdlink', + 'cfs' => 'application/x-cfs-compressed', + 'chat' => 'application/x-chat', + 'pgn' => 'application/x-chess-pgn', + 'nsc' => 'application/x-conference', + 'cpio' => 'application/x-cpio', + 'csh' => 'application/x-csh', + 'deb' => 'application/x-debian-package', + 'dgc' => 'application/x-dgc-compressed', + 'dir' => 'application/x-director', + 'wad' => 'application/x-doom', + 'ncx' => 'application/x-dtbncx+xml', + 'dtb' => 'application/x-dtbook+xml', + 'res' => 'application/x-dtbresource+xml', + 'dvi' => 'application/x-dvi', + 'evy' => 'application/x-envoy', + 'eva' => 'application/x-eva', + 'bdf' => 'application/x-font-bdf', + 'gsf' => 'application/x-font-ghostscript', + 'psf' => 'application/x-font-linux-psf', + 'otf' => 'application/x-font-otf', + 'pcf' => 'application/x-font-pcf', + 'snf' => 'application/x-font-snf', + 'ttf' => 'application/x-font-ttf', + 'pfa' => 'application/x-font-type1', + 'woff' => 'application/x-font-woff', + 'arc' => 'application/x-freearc', + 'spl' => 'application/x-futuresplash', + 'gca' => 'application/x-gca-compressed', + 'ulx' => 'application/x-glulx', + 'gnumeric' => 'application/x-gnumeric', + 'gramps' => 'application/x-gramps-xml', + 'gtar' => 'application/x-gtar', + 'hdf' => 'application/x-hdf', + 'install' => 'application/x-install-instructions', + 'iso' => 'application/x-iso9660-image', + 'jnlp' => 'application/x-java-jnlp-file', + 'latex' => 'application/x-latex', + 'lzh' => 'application/x-lzh-compressed', + 'mie' => 'application/x-mie', + 'prc' => 'application/x-mobipocket-ebook', + 'application' => 'application/x-ms-application', + 'lnk' => 'application/x-ms-shortcut', + 'wmd' => 'application/x-ms-wmd', + 'wmz' => 'application/x-ms-wmz', + 'xbap' => 'application/x-ms-xbap', + 'mdb' => 'application/x-msaccess', + 'obd' => 'application/x-msbinder', + 'crd' => 'application/x-mscardfile', + 'clp' => 'application/x-msclip', + 'exe' => 'application/x-msdownload', + 'mvb' => 'application/x-msmediaview', + 'wmf' => 'application/x-msmetafile', + 'mny' => 'application/x-msmoney', + 'pub' => 'application/x-mspublisher', + 'scd' => 'application/x-msschedule', + 'trm' => 'application/x-msterminal', + 'wri' => 'application/x-mswrite', + 'nc' => 'application/x-netcdf', + 'nzb' => 'application/x-nzb', + 'p12' => 'application/x-pkcs12', + 'p7b' => 'application/x-pkcs7-certificates', + 'p7r' => 'application/x-pkcs7-certreqresp', + 'rar' => 'application/x-rar', + 'ris' => 'application/x-research-info-systems', + 'sh' => 'application/x-sh', + 'shar' => 'application/x-shar', + 'swf' => 'application/x-shockwave-flash', + 'xap' => 'application/x-silverlight-app', + 'sql' => 'application/x-sql', + 'sit' => 'application/x-stuffit', + 'sitx' => 'application/x-stuffitx', + 'srt' => 'application/x-subrip', + 'sv4cpio' => 'application/x-sv4cpio', + 'sv4crc' => 'application/x-sv4crc', + 't3' => 'application/x-t3vm-image', + 'gam' => 'application/x-tads', + 'tar' => 'application/x-tar', + 'tcl' => 'application/x-tcl', + 'tex' => 'application/x-tex', + 'tfm' => 'application/x-tex-tfm', + 'texinfo' => 'application/x-texinfo', + 'obj' => 'application/x-tgif', + 'ustar' => 'application/x-ustar', + 'src' => 'application/x-wais-source', + 'der' => 'application/x-x509-ca-cert', + 'fig' => 'application/x-xfig', + 'xlf' => 'application/x-xliff+xml', + 'xpi' => 'application/x-xpinstall', + 'xz' => 'application/x-xz', + 'z1' => 'application/x-zmachine', + 'xaml' => 'application/xaml+xml', + 'xdf' => 'application/xcap-diff+xml', + 'xenc' => 'application/xenc+xml', + 'xhtml' => 'application/xhtml+xml', + 'xml' => 'application/xml', + 'dtd' => 'application/xml-dtd', + 'xop' => 'application/xop+xml', + 'xpl' => 'application/xproc+xml', + 'xslt' => 'application/xslt+xml', + 'xspf' => 'application/xspf+xml', + 'mxml' => 'application/xv+xml', + 'yang' => 'application/yang', + 'yin' => 'application/yin+xml', + 'zip' => 'application/zip', + 'adp' => 'audio/adpcm', + 'au' => 'audio/basic', + 'mid' => 'audio/midi', + 'mp3' => 'audio/mpeg', + 'mp4a' => 'audio/mp4', + 'mpga' => 'audio/mpeg', + 'oga' => 'audio/ogg', + 's3m' => 'audio/s3m', + 'sil' => 'audio/silk', + 'uva' => 'audio/vnd.dece.audio', + 'eol' => 'audio/vnd.digital-winds', + 'dra' => 'audio/vnd.dra', + 'dts' => 'audio/vnd.dts', + 'dtshd' => 'audio/vnd.dts.hd', + 'lvp' => 'audio/vnd.lucent.voice', + 'pya' => 'audio/vnd.ms-playready.media.pya', + 'ecelp4800' => 'audio/vnd.nuera.ecelp4800', + 'ecelp7470' => 'audio/vnd.nuera.ecelp7470', + 'ecelp9600' => 'audio/vnd.nuera.ecelp9600', + 'rip' => 'audio/vnd.rip', + 'weba' => 'audio/webm', + 'aac' => 'audio/x-aac', + 'aif' => 'audio/x-aiff', + 'caf' => 'audio/x-caf', + 'flac' => 'audio/x-flac', + 'mka' => 'audio/x-matroska', + 'm3u' => 'audio/x-mpegurl', + 'wax' => 'audio/x-ms-wax', + 'wma' => 'audio/x-ms-wma', + 'ram' => 'audio/x-pn-realaudio', + 'rmp' => 'audio/x-pn-realaudio-plugin', + 'wav' => 'audio/x-wav', + 'xm' => 'audio/xm', + 'cdx' => 'chemical/x-cdx', + 'cif' => 'chemical/x-cif', + 'cmdf' => 'chemical/x-cmdf', + 'cml' => 'chemical/x-cml', + 'csml' => 'chemical/x-csml', + 'xyz' => 'chemical/x-xyz', + 'bmp' => 'image/bmp', + 'cgm' => 'image/cgm', + 'g3' => 'image/g3fax', + 'gif' => 'image/gif', + 'ief' => 'image/ief', + 'jpg' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'ktx' => 'image/ktx', + 'png' => 'image/png', + 'btif' => 'image/prs.btif', + 'sgi' => 'image/sgi', + 'svg' => 'image/svg+xml', + 'tiff' => 'image/tiff', + 'psd' => 'image/vnd.adobe.photoshop', + 'uvi' => 'image/vnd.dece.graphic', + 'djvu' => 'image/vnd.djvu', + 'dwg' => 'image/vnd.dwg', + 'dxf' => 'image/vnd.dxf', + 'fbs' => 'image/vnd.fastbidsheet', + 'fpx' => 'image/vnd.fpx', + 'fst' => 'image/vnd.fst', + 'mmr' => 'image/vnd.fujixerox.edmics-mmr', + 'rlc' => 'image/vnd.fujixerox.edmics-rlc', + 'mdi' => 'image/vnd.ms-modi', + 'wdp' => 'image/vnd.ms-photo', + 'npx' => 'image/vnd.net-fpx', + 'wbmp' => 'image/vnd.wap.wbmp', + 'xif' => 'image/vnd.xiff', + 'webp' => 'image/webp', + '3ds' => 'image/x-3ds', + 'ras' => 'image/x-cmu-raster', + 'cmx' => 'image/x-cmx', + 'fh' => 'image/x-freehand', + 'ico' => 'image/x-icon', + 'sid' => 'image/x-mrsid-image', + 'pcx' => 'image/x-pcx', + 'pic' => 'image/x-pict', + 'pnm' => 'image/x-portable-anymap', + 'pbm' => 'image/x-portable-bitmap', + 'pgm' => 'image/x-portable-graymap', + 'ppm' => 'image/x-portable-pixmap', + 'rgb' => 'image/x-rgb', + 'tga' => 'image/x-tga', + 'xbm' => 'image/x-xbitmap', + 'xpm' => 'image/x-xpixmap', + 'xwd' => 'image/x-xwindowdump', + 'eml' => 'message/rfc822', + 'igs' => 'model/iges', + 'msh' => 'model/mesh', + 'dae' => 'model/vnd.collada+xml', + 'dwf' => 'model/vnd.dwf', + 'gdl' => 'model/vnd.gdl', + 'gtw' => 'model/vnd.gtw', + 'mts' => 'model/vnd.mts', + 'vtu' => 'model/vnd.vtu', + 'wrl' => 'model/vrml', + 'x3db' => 'model/x3d+binary', + 'x3dv' => 'model/x3d+vrml', + 'x3d' => 'model/x3d+xml', + 'appcache' => 'text/cache-manifest', + 'ics' => 'text/calendar', + 'css' => 'text/css', + 'csv' => 'text/csv', + 'html' => 'text/html', + 'n3' => 'text/n3', + 'txt' => 'text/plain', + 'dsc' => 'text/prs.lines.tag', + 'rtx' => 'text/richtext', + 'rtf' => 'text/rtf', + 'sgml' => 'text/sgml', + 'tsv' => 'text/tab-separated-values', + 't' => 'text/troff', + 'ttl' => 'text/turtle', + 'uri' => 'text/uri-list', + 'vcard' => 'text/vcard', + 'curl' => 'text/vnd.curl', + 'dcurl' => 'text/vnd.curl.dcurl', + 'scurl' => 'text/vnd.curl.scurl', + 'mcurl' => 'text/vnd.curl.mcurl', + 'sub' => 'text/vnd.dvb.subtitle', + 'fly' => 'text/vnd.fly', + 'flx' => 'text/vnd.fmi.flexstor', + 'gv' => 'text/vnd.graphviz', + '3dml' => 'text/vnd.in3d.3dml', + 'spot' => 'text/vnd.in3d.spot', + 'jad' => 'text/vnd.sun.j2me.app-descriptor', + 'wml' => 'text/vnd.wap.wml', + 'wmls' => 'text/vnd.wap.wmlscript', + 's' => 'text/x-asm', + 'c' => 'text/x-c', + 'f' => 'text/x-fortran', + 'p' => 'text/x-pascal', + 'java' => 'text/x-java-source', + 'opml' => 'text/x-opml', + 'nfo' => 'text/x-nfo', + 'etx' => 'text/x-setext', + 'sfv' => 'text/x-sfv', + 'uu' => 'text/x-uuencode', + 'vcs' => 'text/x-vcalendar', + 'vcf' => 'text/x-vcard', + '3gp' => 'video/3gpp', + '3g2' => 'video/3gpp2', + 'h261' => 'video/h261', + 'h263' => 'video/h263', + 'h264' => 'video/h264', + 'jpgv' => 'video/jpeg', + 'jpm' => 'video/jpm', + 'mj2' => 'video/mj2', + 'mp4' => 'video/mp4', + 'mpeg' => 'video/mpeg', + 'ogv' => 'video/ogg', + 'mov' => 'video/quicktime', + 'qt' => 'video/quicktime', + 'uvh' => 'video/vnd.dece.hd', + 'uvm' => 'video/vnd.dece.mobile', + 'uvp' => 'video/vnd.dece.pd', + 'uvs' => 'video/vnd.dece.sd', + 'uvv' => 'video/vnd.dece.video', + 'dvb' => 'video/vnd.dvb.file', + 'fvt' => 'video/vnd.fvt', + 'mxu' => 'video/vnd.mpegurl', + 'pyv' => 'video/vnd.ms-playready.media.pyv', + 'uvu' => 'video/vnd.uvvu.mp4', + 'viv' => 'video/vnd.vivo', + 'webm' => 'video/webm', + 'f4v' => 'video/x-f4v', + 'fli' => 'video/x-fli', + 'flv' => 'video/x-flv', + 'm4v' => 'video/x-m4v', + 'mkv' => 'video/x-matroska', + 'mng' => 'video/x-mng', + 'asf' => 'video/x-ms-asf', + 'vob' => 'video/x-ms-vob', + 'wm' => 'video/x-ms-wm', + 'wmv' => 'video/x-ms-wmv', + 'wmx' => 'video/x-ms-wmx', + 'wvx' => 'video/x-ms-wvx', + 'avi' => 'video/x-msvideo', + 'movie' => 'video/x-sgi-movie', + 'smv' => 'video/x-smv', + 'ice' => 'x-conference/x-cooltalk', + ]; + + /** + * Get the MIME type for a file based on the file's extension. + * + * @param string $filename + * @return string + */ + public static function from($filename) + { + $extension = strtok(pathinfo($filename, PATHINFO_EXTENSION), '?'); + + return self::getMimeTypeFromExtension($extension); + } + + /** + * Get the MIME type for a given extension or return all mimes. + * + * @param string $extension + * @return string|array + */ + public static function get($extension = null) + { + return $extension ? self::getMimeTypeFromExtension($extension) : self::$mimes; + } + + /** + * Get the MIME type for a given extension. + * + * @param string $extension + * @return string + */ + protected static function getMimeTypeFromExtension($extension) + { + return self::$mimes[$extension] ?? 'application/octet-stream'; + } +} diff --git a/src/Transformers/Request.php b/src/Transformers/Request.php index 4255a235..1dbd41db 100644 --- a/src/Transformers/Request.php +++ b/src/Transformers/Request.php @@ -4,9 +4,9 @@ use Illuminate\Http\Request as IlluminateRequest; use Illuminate\Http\Response as IlluminateResponse; -use Illuminate\Http\Testing\MimeType; use Swoole\Http\Request as SwooleRequest; use SwooleTW\Http\Helpers\FW; +use SwooleTW\Http\Helpers\MimeType; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request as SymfonyRequest; @@ -193,14 +193,8 @@ public static function handleStatic($swooleRequest, $swooleResponse, string $pub return false; } - if (version_compare(FW::version(), '5.4', '>')) { - $contentType = MimeType::get($extension); - } else { - $contentType = static::EXTENSION_MIMES[$extension] ?? mime_content_type($fileName); - } - $swooleResponse->status(IlluminateResponse::HTTP_OK); - $swooleResponse->header('Content-Type', $contentType); + $swooleResponse->header('Content-Type', MimeType::get($extension)); $swooleResponse->sendfile($fileName); return true; diff --git a/tests/Helpers/MimeTypeTest.php b/tests/Helpers/MimeTypeTest.php new file mode 100644 index 00000000..fe8c031d --- /dev/null +++ b/tests/Helpers/MimeTypeTest.php @@ -0,0 +1,25 @@ +assertEquals($mimetype, 'text/css'); + } + + public function testFrom() + { + $filename = 'test.css?id=12d123fadf'; + $mimetype = MimeType::from($filename); + + $this->assertEquals($mimetype, 'text/css'); + } +} From 1033684b6779f66c1855786a388cfe9ad41210cc Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Fri, 1 Feb 2019 22:37:05 +0800 Subject: [PATCH 057/161] fix table prepare for websocket room --- src/Concerns/InteractsWithWebsocket.php | 6 +++++- src/Websocket/Rooms/RedisRoom.php | 8 ++++---- src/Websocket/Rooms/TableRoom.php | 12 ++++++------ 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/Concerns/InteractsWithWebsocket.php b/src/Concerns/InteractsWithWebsocket.php index 8c17bc99..96457c60 100644 --- a/src/Concerns/InteractsWithWebsocket.php +++ b/src/Concerns/InteractsWithWebsocket.php @@ -327,7 +327,11 @@ protected function bindRoom(): void $settings = $config->get("swoole_websocket.settings.{$driver}"); $className = $config->get("swoole_websocket.drivers.{$driver}"); - return $this->createRoom($className, $settings); + // create room instance and initialize + $room = $this->createRoom($className, $settings); + $room->prepare(); + + return $room; }); $this->app->alias(RoomContract::class, 'swoole.room'); diff --git a/src/Websocket/Rooms/RedisRoom.php b/src/Websocket/Rooms/RedisRoom.php index d0d39fd4..2a5ba9e9 100644 --- a/src/Websocket/Rooms/RedisRoom.php +++ b/src/Websocket/Rooms/RedisRoom.php @@ -98,7 +98,7 @@ public function getRedis() */ public function add(int $fd, $rooms) { - $rooms = \is_array($rooms) ? $rooms : [$rooms]; + $rooms = is_array($rooms) ? $rooms : [$rooms]; $this->addValue($fd, $rooms, RoomContract::DESCRIPTORS_KEY); @@ -115,8 +115,8 @@ public function add(int $fd, $rooms) */ public function delete(int $fd, $rooms) { - $rooms = \is_array($rooms) ? $rooms : [$rooms]; - $rooms = \count($rooms) ? $rooms : $this->getRooms($fd); + $rooms = is_array($rooms) ? $rooms : [$rooms]; + $rooms = count($rooms) ? $rooms : $this->getRooms($fd); $this->removeValue($fd, $rooms, RoomContract::DESCRIPTORS_KEY); @@ -203,7 +203,7 @@ public function getRooms(int $fd) protected function checkTable(string $table) { if (! in_array($table, [RoomContract::ROOMS_KEY, RoomContract::DESCRIPTORS_KEY])) { - throw new \InvalidArgumentException('Invalid table name.'); + throw new \InvalidArgumentException("Invalid table name: `{$table}`."); } } diff --git a/src/Websocket/Rooms/TableRoom.php b/src/Websocket/Rooms/TableRoom.php index 4d97d78e..8b5e6fc7 100644 --- a/src/Websocket/Rooms/TableRoom.php +++ b/src/Websocket/Rooms/TableRoom.php @@ -53,7 +53,7 @@ public function prepare(): RoomContract public function add(int $fd, $roomNames) { $rooms = $this->getRooms($fd); - $roomNames = \is_array($roomNames) ? $roomNames : [$roomNames]; + $roomNames = is_array($roomNames) ? $roomNames : [$roomNames]; foreach ($roomNames as $room) { $fds = $this->getClients($room); @@ -80,8 +80,8 @@ public function add(int $fd, $roomNames) public function delete(int $fd, $roomNames = []) { $allRooms = $this->getRooms($fd); - $roomNames = \is_array($roomNames) ? $roomNames : [$roomNames]; - $rooms = \count($roomNames) ? $roomNames : $allRooms; + $roomNames = is_array($roomNames) ? $roomNames : [$roomNames]; + $rooms = count($roomNames) ? $roomNames : $allRooms; $removeRooms = []; foreach ($rooms as $room) { @@ -177,7 +177,7 @@ public function setValue($key, array $value, string $table) { $this->checkTable($table); - $this->$table->set($key, ['value' => \json_encode($value)]); + $this->$table->set($key, ['value' => json_encode($value)]); return $this; } @@ -196,7 +196,7 @@ public function getValue(string $key, string $table) $value = $this->$table->get($key); - return $value ? \json_decode($value['value'], true) : []; + return $value ? json_decode($value['value'], true) : []; } /** @@ -207,7 +207,7 @@ public function getValue(string $key, string $table) protected function checkTable(string $table) { if (! property_exists($this, $table) || ! $this->$table instanceof Table) { - throw new \InvalidArgumentException('Invalid table name.'); + throw new \InvalidArgumentException("Invalid table name: `{$table}`."); } } } From e6bd12d5dde101e5fe1c2b42dcb11e30887250a1 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sat, 2 Feb 2019 15:43:47 +0800 Subject: [PATCH 058/161] Remove some unnecessary dependencies --- composer.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 4f593481..66604a0f 100644 --- a/composer.json +++ b/composer.json @@ -26,11 +26,7 @@ "illuminate/contracts": "~5.3", "illuminate/http": "~5.3", "illuminate/support": "~5.3", - "predis/predis": "^1.1", - "ext-json": "*", - "ext-fileinfo": "*", - "ext-pdo": "*", - "ext-pcntl": "*" + "predis/predis": "^1.1" }, "require-dev": { "laravel/lumen-framework": "~5.3", From d9237e6b5136c416fb89eb23a964154050a923aa Mon Sep 17 00:00:00 2001 From: Ashleigh Hopkins Date: Thu, 7 Feb 2019 14:42:43 +0000 Subject: [PATCH 059/161] Update Response.php Work around issue where you want to return no content. --- src/Transformers/Response.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Transformers/Response.php b/src/Transformers/Response.php index 1f91e05c..e9b3d3cd 100644 --- a/src/Transformers/Response.php +++ b/src/Transformers/Response.php @@ -124,8 +124,10 @@ protected function sendContent() */ protected function sendInChunk($content) { - foreach (str_split($content, 1024) as $v) { - $this->swooleResponse->write($v); + if ($content) { + foreach (str_split($content, 1024) as $v) { + $this->swooleResponse->write($v); + } } $this->swooleResponse->end(); } From 2922c4a87886972dfa5dd07632910b3128399d38 Mon Sep 17 00:00:00 2001 From: marscoo Date: Sun, 17 Feb 2019 16:48:42 +0800 Subject: [PATCH 060/161] Update Manager.php --- src/Server/Manager.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 604d6e37..b2d81fa2 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -255,13 +255,19 @@ protected function resetOnRequest() * Set onTask listener. * * @param mixed $server - * @param string $taskId - * @param string $srcWorkerId - * @param mixed $data + * @param string|\Swoole\Server\Task $taskIdOrTask + * @param string $srcWorkerId Optional + * @param mixed $data Optional */ - public function onTask($server, $taskId, $srcWorkerId, $data) + public function onTask($server, ...$args) { - $this->container->make('events')->fire('swoole.task', func_get_args()); + if ($args[0] instanceof \Swoole\Server\Task && $task = array_shift($args)) { + list($taskId, $srcWorkerId, $data) = [$task->id, $task->worker_id, $task->data]; + } else { + list($taskId, $srcWorkerId, $data) = $args; + } + + $this->container->make('events')->fire('swoole.task', [$server, $taskId, $srcWorkerId, $data]); try { // push websocket message From b6f5b738f9c32d2ef9aaa1d5d93211b89a4fb8fc Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 3 Mar 2019 01:53:31 +0800 Subject: [PATCH 061/161] refactor websocket pusher --- src/Concerns/InteractsWithWebsocket.php | 76 +------ src/Server/Manager.php | 2 +- src/Websocket/Push.php | 204 ----------------- src/Websocket/Pusher.php | 278 ++++++++++++++++++++++++ tests/Server/ManagerTest.php | 67 +++--- tests/Websocket/PusherTest.php | 145 ++++++++++++ 6 files changed, 469 insertions(+), 303 deletions(-) delete mode 100644 src/Websocket/Push.php create mode 100644 src/Websocket/Pusher.php create mode 100644 tests/Websocket/PusherTest.php diff --git a/src/Concerns/InteractsWithWebsocket.php b/src/Concerns/InteractsWithWebsocket.php index 96457c60..19485ec6 100644 --- a/src/Concerns/InteractsWithWebsocket.php +++ b/src/Concerns/InteractsWithWebsocket.php @@ -3,11 +3,10 @@ namespace SwooleTW\Http\Concerns; use Throwable; -use Illuminate\Support\Arr; use Illuminate\Pipeline\Pipeline; use SwooleTW\Http\Server\Sandbox; -use SwooleTW\Http\Websocket\Push; use SwooleTW\Http\Websocket\Parser; +use SwooleTW\Http\Websocket\Pusher; use SwooleTW\Http\Websocket\Websocket; use SwooleTW\Http\Transformers\Request; use SwooleTW\Http\Server\Facades\Server; @@ -158,7 +157,7 @@ public function onClose($server, $fd, $reactorId) */ protected function isWebsocketPushPacket($packet) { - if ( !is_array($packet)) { + if (! is_array($packet)) { return false; } @@ -176,25 +175,11 @@ protected function isWebsocketPushPacket($packet) */ public function pushMessage($server, array $data) { - $push = Push::new($data); - $payload = $this->payloadParser->encode($push->getEvent(), $push->getMessage()); - - // attach sender if not broadcast - if (! $push->isBroadcast() && $push->getSender() && ! $push->hasOwnDescriptor()) { - $push->addDescriptor($push->getSender()); - } - - // check if to broadcast all clients - if ($push->isBroadcastToAllDescriptors()) { - $push->mergeDescriptor($this->filterWebsocket($server->connections)); - } - - // push message to designated fds - foreach ($push->getDescriptors() as $descriptor) { - if ($server->exist($descriptor) || ! $push->isBroadcastToDescriptor((int) $descriptor)) { - $server->push($descriptor, $payload, $push->getOpcode()); - } - } + $pusher = Pusher::make($data, $server); + $pusher->push($this->payloadParser->encode( + $pusher->getEvent(), + $pusher->getMessage() + )); } /** @@ -244,25 +229,8 @@ protected function prepareWebsocket() */ protected function isServerWebsocket(int $fd): bool { - $info = $this->container->make(Server::class)->connection_info($fd); - - return Arr::has($info, 'websocket_status') && Arr::get($info, 'websocket_status'); - } - - /** - * Returns all descriptors that are websocket - * - * @param array $descriptors - * - * @return array - */ - protected function filterWebsocket(array $descriptors): array - { - $callback = function ($descriptor) { - return $this->isServerWebsocket($descriptor); - }; - - return collect($descriptors)->filter($callback)->toArray(); + return $this->container->make(Server::class) + ->connection_info($fd)['websocket_status'] ?? false; } /** @@ -364,26 +332,6 @@ protected function loadWebsocketRoutes() return require $routePath; } - /** - * Normalize data for message push. - * - * @param array $data - * - * @return array - */ - public function normalizePushData(array $data) - { - $opcode = Arr::get($data, 'opcode', 1); - $sender = Arr::get($data, 'sender', 0); - $fds = Arr::get($data, 'fds', []); - $broadcast = Arr::get($data, 'broadcast', false); - $assigned = Arr::get($data, 'assigned', false); - $event = Arr::get($data, 'event', null); - $message = Arr::get($data, 'message', null); - - return [$opcode, $sender, $fds, $broadcast, $assigned, $event, $message]; - } - /** * Indicates if the payload is websocket push. * @@ -391,14 +339,14 @@ public function normalizePushData(array $data) * * @return boolean */ - protected function isWebsocketPushPayload($payload): bool + public function isWebsocketPushPayload($payload): bool { if (! is_array($payload)) { return false; } return $this->isServerWebsocket - && array_key_exists('action', $payload) - && $payload['action'] === Websocket::PUSH_ACTION; + && ($payload['action'] ?? null) === Websocket::PUSH_ACTION + && array_key_exists('data', $payload); } } diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 604d6e37..9b54783a 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -266,7 +266,7 @@ public function onTask($server, $taskId, $srcWorkerId, $data) try { // push websocket message if ($this->isWebsocketPushPayload($data)) { - $this->pushMessage($server, $data['data'] ?? []); + $this->pushMessage($server, $data['data']); // push async task to queue } elseif ($this->isAsyncTaskPayload($data)) { (new SwooleTaskJob($this->container, $server, $data, $taskId, $srcWorkerId))->fire(); diff --git a/src/Websocket/Push.php b/src/Websocket/Push.php deleted file mode 100644 index 6d9c27ab..00000000 --- a/src/Websocket/Push.php +++ /dev/null @@ -1,204 +0,0 @@ -opcode = $opcode; - $this->sender = $sender; - $this->descriptors = $descriptors; - $this->broadcast = $broadcast; - $this->assigned = $assigned; - $this->event = $event; - $this->message = $message; - } - - /** - * Static constructor - * - * @param array $data - * - * @return \SwooleTW\Http\Websocket\Push - */ - public static function new(array $data) - { - $opcode = Arr::get($data, 'opcode', 1); - $sender = Arr::get($data, 'sender', 0); - $descriptors = Arr::get($data, 'fds', []); - $broadcast = Arr::get($data, 'broadcast', false); - $assigned = Arr::get($data, 'assigned', false); - $event = Arr::get($data, 'event', ''); - $message = Arr::get($data, 'message', null); - - return new static($opcode, $sender, $descriptors, $broadcast, $assigned, $event, $message); - } - - /** - * @return int - */ - public function getOpcode(): int - { - return $this->opcode; - } - - /** - * @return int - */ - public function getSender(): int - { - return $this->sender; - } - - /** - * @return array - */ - public function getDescriptors(): array - { - return $this->descriptors; - } - - /** - * @param int $descriptor - */ - public function addDescriptor($descriptor): void - { - $this->descriptors[] = $descriptor; - } - - /** - * @param array $descriptors - */ - public function mergeDescriptor(array $descriptors): void - { - $this->descriptors[] = array_merge($this->descriptors, $descriptors); - } - - /** - * @param int $descriptor - * - * @return bool - */ - public function hasDescriptor(int $descriptor): bool - { - return in_array($descriptor, $this->descriptors, true); - } - - /** - * @return bool - */ - public function hasOwnDescriptor(): bool - { - return $this->hasDescriptor($this->sender); - } - - /** - * @return bool - */ - public function isBroadcast(): bool - { - return $this->broadcast; - } - - /** - * @return bool - */ - public function isAssigned(): bool - { - return $this->assigned; - } - - /** - * @return string - */ - public function getEvent(): string - { - return $this->event; - } - - /** - * @return string|null - */ - public function getMessage(): ?string - { - return $this->message; - } - - /** - * @return bool - */ - public function isBroadcastToAllDescriptors(): bool - { - return $this->isBroadcast() && ! $this->isAssigned() && count($this->descriptors) > 0; - } - - /** - * @param int $descriptor - * - * @return bool - */ - public function isBroadcastToDescriptor(int $descriptor): bool - { - return $this->isBroadcast() && $this->getSender() === $descriptor; - } -} \ No newline at end of file diff --git a/src/Websocket/Pusher.php b/src/Websocket/Pusher.php new file mode 100644 index 00000000..b63b1b7c --- /dev/null +++ b/src/Websocket/Pusher.php @@ -0,0 +1,278 @@ +opcode = $opcode; + $this->sender = $sender; + $this->descriptors = $descriptors; + $this->broadcast = $broadcast; + $this->assigned = $assigned; + $this->event = $event; + $this->message = $message; + $this->server = $server; + } + + /** + * Static constructor + * + * @param array $data + * @param \Swoole\Websocket\Server $server + * + * @return \SwooleTW\Http\Websocket\Push + */ + public static function make(array $data, $server) + { + return new static( + $data['opcode'] ?? 1, + $data['sender'] ?? 0, + $data['fds'] ?? [], + $data['broadcast'] ?? false, + $data['assigned'] ?? false, + $data['event'] ?? null, + $data['message'] ?? null, + $server + ); + } + + /** + * @return int + */ + public function getOpcode(): int + { + return $this->opcode; + } + + /** + * @return int + */ + public function getSender(): int + { + return $this->sender; + } + + /** + * @return array + */ + public function getDescriptors(): array + { + return $this->descriptors; + } + + /** + * @param int $descriptor + * + * @return self + */ + public function addDescriptor($descriptor): self + { + return $this->addDescriptors([$descriptor]); + } + + /** + * @param array $descriptors + * + * @return self + */ + public function addDescriptors(array $descriptors): self + { + $this->descriptors = array_values( + array_unique( + array_merge($this->descriptors, $descriptors) + ) + ); + + return $this; + } + + /** + * @param int $descriptor + * + * @return bool + */ + public function hasDescriptor(int $descriptor): bool + { + return in_array($descriptor, $this->descriptors); + } + + /** + * @return bool + */ + public function isBroadcast(): bool + { + return $this->broadcast; + } + + /** + * @return bool + */ + public function isAssigned(): bool + { + return $this->assigned; + } + + /** + * @return string + */ + public function getEvent(): string + { + return $this->event; + } + + /** + * @return string|null + */ + public function getMessage(): ?string + { + return $this->message; + } + + /** + * @return \Swoole\Websocket\Server + */ + public function getServer() + { + return $this->server; + } + + /** + * @return bool + */ + public function shouldBroadcast(): bool + { + return $this->broadcast && empty($this->descriptors) && ! $this->assigned; + } + + /** + * Check if it's a websocket fd. + * + * @param int $fd + * + * @return bool + */ + public function isServerWebsocket(int $fd): bool + { + return $this->server->connection_info($fd)['websocket_status'] ?? false; + } + + /** + * Returns all descriptors that are websocket + * + * @param \Swoole\Connection\Iterator $descriptors + * + * @return array + */ + protected function getWebsocketConnections(): array + { + return array_filter(iterator_to_array($this->server->connections), function ($fd) { + return $this->isServerWebsocket($fd); + }); + } + + /** + * @param int $fd + * + * @return bool + */ + public function shouldPushToDescriptor(int $fd): bool + { + return $this->server->exist($fd) + && ($this->broadcast && $this->sender !== (int) $fd); + } + + /** + * Push message to related descriptors + * + * @param mixed $payload + * + * @return void + */ + public function push($payload): void + { + // attach sender if not broadcast + if (! $this->broadcast && $this->sender && ! $this->hasDescriptor($this->sender)) { + $this->addDescriptor($this->sender); + } + + // check if to broadcast to other clients + if ($this->shouldBroadcast()) { + $this->addDescriptors($this->getWebsocketConnections()); + } + + // push message to designated fds + foreach ($this->descriptors as $descriptor) { + if ($this->shouldPushToDescriptor($descriptor)) { + $this->server->push($descriptor, $payload, $this->opcode); + } + } + } +} \ No newline at end of file diff --git a/tests/Server/ManagerTest.php b/tests/Server/ManagerTest.php index a667003b..a217f15b 100644 --- a/tests/Server/ManagerTest.php +++ b/tests/Server/ManagerTest.php @@ -2,28 +2,29 @@ namespace SwooleTW\Http\Tests\Server; -use Illuminate\Container\Container; -use Illuminate\Contracts\Debug\ExceptionHandler; -use Illuminate\Support\Facades\Config; -use Laravel\Lumen\Exceptions\Handler; use Mockery as m; +use Swoole\Table; use Swoole\Http\Request; use Swoole\Http\Response; -use Swoole\Table; -use SwooleTW\Http\Server\Facades\Server; use SwooleTW\Http\Server\Manager; use SwooleTW\Http\Server\Sandbox; -use SwooleTW\Http\Table\SwooleTable; use SwooleTW\Http\Tests\TestCase; -use SwooleTW\Http\Websocket\Facades\Websocket as WebsocketFacade; -use SwooleTW\Http\Websocket\HandlerContract; +use Illuminate\Container\Container; use SwooleTW\Http\Websocket\Parser; -use SwooleTW\Http\Websocket\Rooms\RoomContract; +use SwooleTW\Http\Table\SwooleTable; +use Laravel\Lumen\Exceptions\Handler; +use Illuminate\Support\Facades\Config; +use SwooleTW\Http\Websocket\Websocket; +use SwooleTW\Http\Server\Facades\Server; +use SwooleTW\Http\Websocket\Facades\Pusher; +use SwooleTW\Http\Websocket\HandlerContract; use SwooleTW\Http\Websocket\Rooms\TableRoom; +use SwooleTW\Http\Websocket\Rooms\RoomContract; +use Illuminate\Contracts\Debug\ExceptionHandler; use SwooleTW\Http\Websocket\SocketIO\SocketIOParser; use SwooleTW\Http\Websocket\SocketIO\WebsocketHandler; -use SwooleTW\Http\Websocket\Websocket; use Illuminate\Contracts\Config\Repository as ConfigContract; +use SwooleTW\Http\Websocket\Facades\Websocket as WebsocketFacade; class ManagerTest extends TestCase { @@ -526,36 +527,35 @@ public function testOnClose() $manager->onClose('server', $fd, 'reactorId'); } - public function testNormalizePushMessage() + public function testIsWebsocketPushPayload() { - $data = [ - 'opcode' => 'opcode', - 'sender' => 'sender', - 'fds' => 'fds', - 'broadcast' => 'broadcast', - 'assigned' => 'assigned', - 'event' => 'event', - 'message' => 'message', + $payload = [ + 'action' => 'push', + 'data' => [ + 'opcode' => 'opcode', + 'sender' => 'sender', + 'fds' => 'fds', + 'broadcast' => 'broadcast', + 'assigned' => 'assigned', + 'event' => 'event', + 'message' => 'message', + ] ]; $manager = $this->getWebsocketManager(); - $result = $manager->normalizePushData($data); - - $this->assertSame($data['opcode'], $result[0]); - $this->assertSame($data['sender'], $result[1]); - $this->assertSame($data['fds'], $result[2]); - $this->assertSame($data['broadcast'], $result[3]); - $this->assertSame($data['assigned'], $result[4]); - $this->assertSame($data['event'], $result[5]); - $this->assertSame($data['message'], $result[6]); + + $this->assertTrue($manager->isWebsocketPushPayload($payload)); + $this->assertFalse($manager->isWebsocketPushPayload(['foo' => 'bar'])); } public function testPushMessage() { $data = [ + 'sender' => 1, 'fds' => [1, 2, 3], - 'event' => 'event', - 'message' => 'message', + 'event' => $event = 'event', + 'message' => $message = 'message', + 'broadcast' => true ]; $parser = m::mock(Parser::class); @@ -566,10 +566,9 @@ public function testPushMessage() $server = m::mock('server'); $server->shouldReceive('exist') - ->times(count($data['fds'])) - ->andReturn(true); + ->andReturn(true); $server->shouldReceive('push') - ->times(count($data['fds'])); + ->twice(); $manager = $this->getWebsocketManager(); $manager->setPayloadParser($parser); diff --git a/tests/Websocket/PusherTest.php b/tests/Websocket/PusherTest.php new file mode 100644 index 00000000..0d97a0b7 --- /dev/null +++ b/tests/Websocket/PusherTest.php @@ -0,0 +1,145 @@ + 1, + 'sender' => 3, + 'fds' => [1, 2], + 'broadcast' => true, + 'assigned' => true, + 'event' => 'event', + 'message' => 'message' + ]; + $pusher = Pusher::make($data, null); + + $this->assertInstanceOf(Pusher::class, $pusher); + $this->assertSame($data['opcode'], $pusher->getOpCode()); + $this->assertSame($data['sender'], $pusher->getSender()); + $this->assertSame($data['fds'], $pusher->getDescriptors()); + $this->assertSame($data['opcode'], $pusher->getOpCode()); + $this->assertSame($data['broadcast'], $pusher->isBroadCast()); + $this->assertSame($data['assigned'], $pusher->isAssigned()); + $this->assertSame($data['event'], $pusher->getEvent()); + $this->assertSame($data['message'], $pusher->getMessage()); + } + + public function testAddDescriptor() + { + $pusher = Pusher::make([ + 'opcode' => 1, + 'sender' => 3, + 'fds' => [1, 2], + 'broadcast' => true, + 'assigned' => true, + 'event' => 'event', + 'message' => 'message' + ], null); + + $pusher->addDescriptor(3); + $this->assertSame([1, 2, 3], $pusher->getDescriptors()); + + $pusher->addDescriptor(1); + $this->assertSame([1, 2, 3], $pusher->getDescriptors()); + } + + public function testAddDescriptors() + { + $pusher = Pusher::make([ + 'opcode' => 1, + 'sender' => 3, + 'fds' => [1, 2], + 'broadcast' => true, + 'assigned' => true, + 'event' => 'event', + 'message' => 'message' + ], null); + + $pusher->addDescriptors([3]); + $this->assertSame([1, 2, 3], $pusher->getDescriptors()); + + $pusher->addDescriptors([1, 4]); + $this->assertSame([1, 2, 3, 4], $pusher->getDescriptors()); + } + + public function testHasDescriptor() + { + $pusher = Pusher::make([ + 'opcode' => 1, + 'sender' => 3, + 'fds' => [1, 2], + 'broadcast' => true, + 'assigned' => true, + 'event' => 'event', + 'message' => 'message' + ], null); + + $this->assertTrue($pusher->hasDescriptor(1)); + $this->assertTrue($pusher->hasDescriptor(2)); + $this->assertFalse($pusher->hasDescriptor(3)); + } + + public function testShouldBroadcast() + { + $server = m::mock(Server::class); + $server->shouldReceive('connection_info') + ->with($fd = 1) + ->once() + ->andReturn([ + 'websocket_status' => true + ]); + + $pusher = Pusher::make([ + 'opcode' => 1, + 'sender' => 3, + 'fds' => [], + 'broadcast' => true, + 'assigned' => false, + 'event' => 'event', + 'message' => 'message' + ], $server); + + $this->assertTrue($pusher->isServerWebsocket($fd)); + } + + public function testShouldPushToDescriptor() + { + $server = m::mock(Server::class); + $server->shouldReceive('exist') + ->with($fd = 1) + ->twice() + ->andReturn(true); + + $pusher = Pusher::make([ + 'opcode' => 1, + 'sender' => 3, + 'fds' => [], + 'broadcast' => true, + 'assigned' => false, + 'event' => 'event', + 'message' => 'message' + ], $server); + + $this->assertTrue($pusher->shouldPushToDescriptor($fd)); + + $pusher = Pusher::make([ + 'opcode' => 1, + 'sender' => 1, + 'fds' => [], + 'broadcast' => true, + 'assigned' => false, + 'event' => 'event', + 'message' => 'message' + ], $server); + + $this->assertFalse($pusher->shouldPushToDescriptor($fd)); + } +} From 6f2d74163e32adbe5dcad8b6b904646e7cbc8740 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 3 Mar 2019 16:47:11 +0800 Subject: [PATCH 062/161] enhance registerDatabaseDriver --- src/HttpServiceProvider.php | 38 +++++++++++------------------------ src/Transformers/Response.php | 1 + 2 files changed, 13 insertions(+), 26 deletions(-) diff --git a/src/HttpServiceProvider.php b/src/HttpServiceProvider.php index 36f5d688..3e1f2709 100644 --- a/src/HttpServiceProvider.php +++ b/src/HttpServiceProvider.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http; -use Illuminate\Support\Arr; use SwooleTW\Http\Helpers\FW; use Illuminate\Queue\QueueManager; use Illuminate\Contracts\Http\Kernel; @@ -177,17 +176,17 @@ protected function registerDatabaseDriver() { $this->app->extend(DatabaseManager::class, function (DatabaseManager $db) { $db->extend('mysql-coroutine', function ($config, $name) { - $config = $this->getMergedDatabaseConfig($config, $name); + $config['name'] = $name; $connection = new MySqlConnection( - $this->getNewMySqlConnection($config), - Arr::get($config, 'database'), - Arr::get($config, 'prefix'), + $this->getNewMySqlConnection($config, 'write'), + $config['database'], + $config['prefix'], $config ); - if (Arr::has($config, 'read')) { - $connection->setReadPdo($this->getNewMySqlConnection($config)); + if (isset($config['read'])) { + $connection->setReadPdo($this->getNewMySqlConnection($config, 'read')); } return $connection; @@ -197,33 +196,20 @@ protected function registerDatabaseDriver() }); } - /** - * Get mereged config for coroutine mysql. - * - * @param array $config - * @param string $name - * - * @return array - */ - protected function getMergedDatabaseConfig(array $config, string $name) - { - $newConfig = $config; - $newConfig = Arr::add($newConfig, 'name', $name); - $newConfig = array_merge($newConfig, Arr::get($newConfig, 'read', [])); - $newConfig = array_merge($newConfig, Arr::get($newConfig, 'write', [])); - - return $newConfig; - } - /** * Get a new mysql connection. * * @param array $config + * @param string $connection * * @return \PDO */ - protected function getNewMySqlConnection(array $config) + protected function getNewMySqlConnection(array $config, string $connection = null) { + if ($connection && isset($config[$connection])) { + $config = array_merge($config, $config[$connection]); + } + return ConnectorFactory::make(FW::version())->connect($config); } diff --git a/src/Transformers/Response.php b/src/Transformers/Response.php index e9b3d3cd..6c7e053a 100644 --- a/src/Transformers/Response.php +++ b/src/Transformers/Response.php @@ -129,6 +129,7 @@ protected function sendInChunk($content) $this->swooleResponse->write($v); } } + $this->swooleResponse->end(); } From 1952a9aabe4d573f82ce5ff32be00011d570881d Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 3 Mar 2019 17:26:53 +0800 Subject: [PATCH 063/161] output error message to console when server error occurred --- src/Server/Manager.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 9b54783a..16af8e69 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -18,6 +18,7 @@ use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Debug\ExceptionHandler; use SwooleTW\Http\Concerns\InteractsWithWebsocket; +use Symfony\Component\Console\Output\ConsoleOutput; use SwooleTW\Http\Concerns\InteractsWithSwooleQueue; use SwooleTW\Http\Concerns\InteractsWithSwooleTable; use Symfony\Component\Debug\Exception\FatalThrowableError; @@ -420,11 +421,13 @@ protected function isInTesting() */ public function logServerError(Throwable $e) { - $this->container - ->make(ExceptionHandler::class) - ->report( - $this->normalizeException($e) - ); + $exception = $this->normalizeException($e); + + $this->container->make(ConsoleOutput::class) + ->writeln(sprintf("%s", $exception)); + + $this->container->make(ExceptionHandler::class) + ->report($exception); } /** From 44cb1381242f64571d92e3795b2e56f79851901b Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 3 Mar 2019 17:32:43 +0800 Subject: [PATCH 064/161] comment testGetIlluminateResponse temprarily --- tests/Transformers/ResponseTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/Transformers/ResponseTest.php b/tests/Transformers/ResponseTest.php index 41df5999..9c19fa30 100644 --- a/tests/Transformers/ResponseTest.php +++ b/tests/Transformers/ResponseTest.php @@ -16,13 +16,13 @@ public function testMake() $this->assertInstanceOf(Response::class, $response); } - public function testGetIlluminateResponse() - { - $response = Response::make(new IlluminateResponse, new SwooleResponse); - $illuminateResponse = $response->getIlluminateResponse(); + // public function testGetIlluminateResponse() + // { + // $response = Response::make(new IlluminateResponse, new SwooleResponse); + // $illuminateResponse = $response->getIlluminateResponse(); - $this->assertInstanceOf(IlluminateResponse::class, $illuminateResponse); - } + // $this->assertInstanceOf(IlluminateResponse::class, $illuminateResponse); + // } public function testGetSwooleResponse() { From f0d53cf8d0ec157087090ef07d3b9fb1ad7792e6 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 3 Mar 2019 17:42:44 +0800 Subject: [PATCH 065/161] exclude testing mode for logServerError --- src/Server/Manager.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 16af8e69..1962bc20 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -421,8 +421,11 @@ protected function isInTesting() */ public function logServerError(Throwable $e) { - $exception = $this->normalizeException($e); + if ($this->isInTesting()) { + return; + } + $exception = $this->normalizeException($e); $this->container->make(ConsoleOutput::class) ->writeln(sprintf("%s", $exception)); From dd50b42bc187a06630d56119f2d212a04e7fb227 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 3 Mar 2019 17:58:55 +0800 Subject: [PATCH 066/161] test response for debug --- src/Transformers/Response.php | 6 ++++++ tests/Transformers/ResponseTest.php | 13 +++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/Transformers/Response.php b/src/Transformers/Response.php index 6c7e053a..bcb26fad 100644 --- a/src/Transformers/Response.php +++ b/src/Transformers/Response.php @@ -177,4 +177,10 @@ public function getIlluminateResponse() { return $this->illuminateResponse; } + + // test only + public function getResponseClass() + { + return get_class($this->illuminateResponse); + } } diff --git a/tests/Transformers/ResponseTest.php b/tests/Transformers/ResponseTest.php index 9c19fa30..53386c56 100644 --- a/tests/Transformers/ResponseTest.php +++ b/tests/Transformers/ResponseTest.php @@ -16,13 +16,14 @@ public function testMake() $this->assertInstanceOf(Response::class, $response); } - // public function testGetIlluminateResponse() - // { - // $response = Response::make(new IlluminateResponse, new SwooleResponse); - // $illuminateResponse = $response->getIlluminateResponse(); + public function testGetIlluminateResponse() + { + $response = Response::make(new IlluminateResponse, new SwooleResponse); + $this->assertSame(IlluminateResponse::class, $response->getResponseClass()); + // $illuminateResponse = $response->getIlluminateResponse(); - // $this->assertInstanceOf(IlluminateResponse::class, $illuminateResponse); - // } + // $this->assertInstanceOf(IlluminateResponse::class, $illuminateResponse); + } public function testGetSwooleResponse() { From 8fa56e624af3dd887791e0ac01472ae6fb7fc690 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 3 Mar 2019 18:05:37 +0800 Subject: [PATCH 067/161] test response again --- src/Transformers/Response.php | 6 ------ tests/Transformers/ResponseTest.php | 4 ++-- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/Transformers/Response.php b/src/Transformers/Response.php index bcb26fad..6c7e053a 100644 --- a/src/Transformers/Response.php +++ b/src/Transformers/Response.php @@ -177,10 +177,4 @@ public function getIlluminateResponse() { return $this->illuminateResponse; } - - // test only - public function getResponseClass() - { - return get_class($this->illuminateResponse); - } } diff --git a/tests/Transformers/ResponseTest.php b/tests/Transformers/ResponseTest.php index 53386c56..71b7f181 100644 --- a/tests/Transformers/ResponseTest.php +++ b/tests/Transformers/ResponseTest.php @@ -19,9 +19,9 @@ public function testMake() public function testGetIlluminateResponse() { $response = Response::make(new IlluminateResponse, new SwooleResponse); - $this->assertSame(IlluminateResponse::class, $response->getResponseClass()); - // $illuminateResponse = $response->getIlluminateResponse(); + $illuminateResponse = $response->getIlluminateResponse(); + $this->assertSame(IlluminateResponse::class, get_class($illuminateResponse)); // $this->assertInstanceOf(IlluminateResponse::class, $illuminateResponse); } From 4c8a06209b1116b5a4e8ba5bad31490f7a6e9273 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 3 Mar 2019 18:31:33 +0800 Subject: [PATCH 068/161] pass full args to task event --- src/Server/Manager.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 522b90a3..9b0f8e1b 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -262,13 +262,7 @@ protected function resetOnRequest() */ public function onTask($server, ...$args) { - if ($args[0] instanceof \Swoole\Server\Task && $task = array_shift($args)) { - list($taskId, $srcWorkerId, $data) = [$task->id, $task->worker_id, $task->data]; - } else { - list($taskId, $srcWorkerId, $data) = $args; - } - - $this->container->make('events')->fire('swoole.task', [$server, $taskId, $srcWorkerId, $data]); + $this->container->make('events')->fire('swoole.task', [$server, ...$args]); try { // push websocket message From 59828bfc5937d0431f15404c234df5e88aa80ce4 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 3 Mar 2019 18:32:05 +0800 Subject: [PATCH 069/161] test getIlluminateResponse again --- tests/Transformers/ResponseTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/Transformers/ResponseTest.php b/tests/Transformers/ResponseTest.php index 71b7f181..41df5999 100644 --- a/tests/Transformers/ResponseTest.php +++ b/tests/Transformers/ResponseTest.php @@ -21,8 +21,7 @@ public function testGetIlluminateResponse() $response = Response::make(new IlluminateResponse, new SwooleResponse); $illuminateResponse = $response->getIlluminateResponse(); - $this->assertSame(IlluminateResponse::class, get_class($illuminateResponse)); - // $this->assertInstanceOf(IlluminateResponse::class, $illuminateResponse); + $this->assertInstanceOf(IlluminateResponse::class, $illuminateResponse); } public function testGetSwooleResponse() From 9e7728047aafe42864896176622800e2ce2c9e0e Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 3 Mar 2019 18:40:52 +0800 Subject: [PATCH 070/161] fix stupid syntax error --- src/Server/Manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 9b0f8e1b..fa0ce1e9 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -262,7 +262,7 @@ protected function resetOnRequest() */ public function onTask($server, ...$args) { - $this->container->make('events')->fire('swoole.task', [$server, ...$args]); + $this->container->make('events')->fire('swoole.task', [$server, $args]); try { // push websocket message From 2a5568ab2cc3296cc4d5cb98a26a06b24996f6d0 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 3 Mar 2019 18:58:20 +0800 Subject: [PATCH 071/161] require minimal laravel version to 5.4 and support 5.8 --- .travis.yml | 4 +--- README.md | 2 +- src/Server/Manager.php | 16 ++++++++-------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 15df5365..3ea2633d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,6 @@ sudo: false matrix: include: - - php: 7.2 - env: FRAMEWORK_VERSION=laravel/framework:5.3.* - php: 7.2 env: FRAMEWORK_VERSION=laravel/framework:5.4.* - php: 7.2 @@ -15,7 +13,7 @@ matrix: - php: 7.2 env: FRAMEWORK_VERSION=laravel/framework:5.7.* - php: 7.2 - env: FRAMEWORK_VERSION=laravel/lumen-framework:5.3.* + env: FRAMEWORK_VERSION=laravel/framework:5.8.* - php: 7.2 env: FRAMEWORK_VERSION=laravel/lumen-framework:5.4.* - php: 7.2 diff --git a/README.md b/README.md index 2b8206a1..0fc49176 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This package provides a high performance HTTP server to speed up your Laravel/Lu | PHP | Laravel | Lumen | Swoole | |:-------:|:-------:|:-----:|:-------:| -| >=7.2 | ~5.3 | ~5.3 | >=4.0.0 | +| >=7.2 | ~5.4 | ~5.4 | >=4.0.0 | ## Features diff --git a/src/Server/Manager.php b/src/Server/Manager.php index fa0ce1e9..b93e66c9 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -123,7 +123,7 @@ protected function setSwooleServerListeners() foreach ($this->events as $event) { $listener = Str::camel("on_$event"); $callback = method_exists($this, $listener) ? [$this, $listener] : function () use ($event) { - $this->container->make('events')->fire("swoole.$event", func_get_args()); + $this->container->make('events')->dispatch("swoole.$event", func_get_args()); }; $this->container->make(Server::class)->on($event, $callback); @@ -138,7 +138,7 @@ public function onStart() $this->setProcessName('master process'); $this->createPidFile(); - $this->container->make('events')->fire('swoole.start', func_get_args()); + $this->container->make('events')->dispatch('swoole.start', func_get_args()); } /** @@ -149,7 +149,7 @@ public function onStart() public function onManagerStart() { $this->setProcessName('manager process'); - $this->container->make('events')->fire('swoole.managerStart', func_get_args()); + $this->container->make('events')->dispatch('swoole.managerStart', func_get_args()); } /** @@ -163,7 +163,7 @@ public function onWorkerStart($server) { $this->clearCache(); - $this->container->make('events')->fire('swoole.workerStart', func_get_args()); + $this->container->make('events')->dispatch('swoole.workerStart', func_get_args()); // don't init laravel app in task workers if ($server->taskworker) { @@ -197,7 +197,7 @@ public function onWorkerStart($server) */ public function onRequest($swooleRequest, $swooleResponse) { - $this->app->make('events')->fire('swoole.request'); + $this->app->make('events')->dispatch('swoole.request'); $this->resetOnRequest(); $sandbox = $this->app->make(Sandbox::class); @@ -262,7 +262,7 @@ protected function resetOnRequest() */ public function onTask($server, ...$args) { - $this->container->make('events')->fire('swoole.task', [$server, $args]); + $this->container->make('events')->dispatch('swoole.task', [$server, $args]); try { // push websocket message @@ -270,7 +270,7 @@ public function onTask($server, ...$args) $this->pushMessage($server, $data['data']); // push async task to queue } elseif ($this->isAsyncTaskPayload($data)) { - (new SwooleTaskJob($this->container, $server, $data, $taskId, $srcWorkerId))->fire(); + (new SwooleTaskJob($this->container, $server, $data, $taskId, $srcWorkerId))->dispatch(); } } catch (Throwable $e) { $this->logServerError($e); @@ -287,7 +287,7 @@ public function onTask($server, ...$args) public function onFinish($server, $taskId, $data) { // task worker callback - $this->container->make('events')->fire('swoole.finish', func_get_args()); + $this->container->make('events')->dispatch('swoole.finish', func_get_args()); return; } From 11fe8f0997163dda815f20542816333306a40932 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 3 Mar 2019 19:06:40 +0800 Subject: [PATCH 072/161] fix managerTest for mocking event --- tests/Server/ManagerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Server/ManagerTest.php b/tests/Server/ManagerTest.php index a217f15b..add08370 100644 --- a/tests/Server/ManagerTest.php +++ b/tests/Server/ManagerTest.php @@ -636,7 +636,7 @@ protected function getConfig($websocket = false) protected function getEvent($name, $default = true) { $event = m::mock('event') - ->shouldReceive('fire') + ->shouldReceive('dispatch') ->with($name, m::any()) ->once(); From 4b1d5109b01980d91e1eda9a9063b59d3c8908b7 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 3 Mar 2019 20:13:00 +0800 Subject: [PATCH 073/161] update required dependency version for laravel --- .travis.yml | 4 ++-- composer.json | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3ea2633d..e7275047 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,8 +12,8 @@ matrix: env: FRAMEWORK_VERSION=laravel/framework:5.6.* - php: 7.2 env: FRAMEWORK_VERSION=laravel/framework:5.7.* - - php: 7.2 - env: FRAMEWORK_VERSION=laravel/framework:5.8.* + # - php: 7.2 + # env: FRAMEWORK_VERSION=laravel/framework:5.8.* - php: 7.2 env: FRAMEWORK_VERSION=laravel/lumen-framework:5.4.* - php: 7.2 diff --git a/composer.json b/composer.json index 66604a0f..69c534aa 100644 --- a/composer.json +++ b/composer.json @@ -22,14 +22,14 @@ ], "require": { "php": "^7.2", - "illuminate/console": "~5.3", - "illuminate/contracts": "~5.3", - "illuminate/http": "~5.3", - "illuminate/support": "~5.3", + "illuminate/console": "~5.4", + "illuminate/contracts": "~5.4", + "illuminate/http": "~5.4", + "illuminate/support": "~5.4", "predis/predis": "^1.1" }, "require-dev": { - "laravel/lumen-framework": "~5.3", + "laravel/lumen-framework": "~5.4", "phpunit/phpunit": "^7.5", "phpunit/php-code-coverage": "^6.1", "php-coveralls/php-coveralls": "^2.1", From 705a9809e2e352513315748b5aa398a0035fd884 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 3 Mar 2019 23:07:36 +0800 Subject: [PATCH 074/161] add raw cookie support back to response --- src/Transformers/Response.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Transformers/Response.php b/src/Transformers/Response.php index 6c7e053a..2fd6e306 100644 --- a/src/Transformers/Response.php +++ b/src/Transformers/Response.php @@ -86,9 +86,11 @@ protected function sendHeaders() $this->swooleResponse->status($illuminateResponse->getStatusCode()); // cookies + // $cookie->isRaw() is supported after symfony/http-foundation 3.1 + // and Laravel 5.3, so we can add it back now foreach ($illuminateResponse->headers->getCookies() as $cookie) { - // may need to consider rawcookie - $this->swooleResponse->cookie( + $method = $cookie->isRaw() ? 'rawcookie' : 'cookie'; + $this->swooleResponse->$method( $cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), From b341335e098a3a3335554086357a63f9ce569739 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 3 Mar 2019 23:58:23 +0800 Subject: [PATCH 075/161] check strlen for response content --- src/Transformers/Response.php | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/Transformers/Response.php b/src/Transformers/Response.php index 2fd6e306..f51ce3b2 100644 --- a/src/Transformers/Response.php +++ b/src/Transformers/Response.php @@ -10,6 +10,8 @@ class Response { + const CHUNK_SIZE = 1024; + /** * @var \Swoole\Http\Response */ @@ -46,7 +48,7 @@ public function __construct($illuminateResponse, SwooleResponse $swooleResponse) } /** - * Sends HTTP headers and content. + * Send HTTP headers and content. * * @throws \InvalidArgumentException */ @@ -57,7 +59,7 @@ public function send() } /** - * Sends HTTP headers. + * Send HTTP headers. * * @throws \InvalidArgumentException */ @@ -103,7 +105,7 @@ protected function sendHeaders() } /** - * Sends HTTP content. + * Send HTTP content. */ protected function sendContent() { @@ -126,10 +128,13 @@ protected function sendContent() */ protected function sendInChunk($content) { - if ($content) { - foreach (str_split($content, 1024) as $v) { - $this->swooleResponse->write($v); - } + if (strlen($content) <= static::CHUNK_SIZE) { + $this->swooleResponse->end($content); + return; + } + + foreach (str_split($content, static::CHUNK_SIZE) as $chunk) { + $this->swooleResponse->write($chunk); } $this->swooleResponse->end(); From 5d1a7d067070842228f1462376c5e69d55fdb925 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Tue, 5 Mar 2019 21:39:17 +0800 Subject: [PATCH 076/161] revert task_enable_coroutine support --- src/Server/Manager.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Server/Manager.php b/src/Server/Manager.php index b93e66c9..4258a707 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -5,6 +5,7 @@ use Exception; use Throwable; use Swoole\Process; +use Swoole\Server\Task; use Illuminate\Support\Str; use SwooleTW\Http\Helpers\OS; use SwooleTW\Http\Server\Sandbox; @@ -256,13 +257,13 @@ protected function resetOnRequest() * Set onTask listener. * * @param mixed $server - * @param string|\Swoole\Server\Task $taskIdOrTask - * @param string $srcWorkerId Optional - * @param mixed $data Optional + * @param string|\Swoole\Server\Task $taskId or $task + * @param string $srcWorkerId + * @param mixed $data */ - public function onTask($server, ...$args) + public function onTask($server, $taskId, $srcWorkerId, $data) { - $this->container->make('events')->dispatch('swoole.task', [$server, $args]); + $this->container->make('events')->dispatch('swoole.task', func_get_args()); try { // push websocket message From 0a39cad2db1f049524d3a6487328aa8acb6d664f Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Tue, 5 Mar 2019 22:23:58 +0800 Subject: [PATCH 077/161] adjust chunk size for response to 8k --- src/Transformers/Response.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Transformers/Response.php b/src/Transformers/Response.php index f51ce3b2..416a26fa 100644 --- a/src/Transformers/Response.php +++ b/src/Transformers/Response.php @@ -10,7 +10,7 @@ class Response { - const CHUNK_SIZE = 1024; + const CHUNK_SIZE = 8192; /** * @var \Swoole\Http\Response From 2e640940ca2e182497b6afc2bda204a064fc397d Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Thu, 7 Mar 2019 00:38:26 +0800 Subject: [PATCH 078/161] fix accessLog middleware in lumen --- src/HttpServiceProvider.php | 15 ++++++++++----- src/LaravelServiceProvider.php | 17 +++++++++++++++-- src/LumenServiceProvider.php | 16 ++++++++++++++-- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/HttpServiceProvider.php b/src/HttpServiceProvider.php index 3e1f2709..23a7caa3 100644 --- a/src/HttpServiceProvider.php +++ b/src/HttpServiceProvider.php @@ -4,10 +4,8 @@ use SwooleTW\Http\Helpers\FW; use Illuminate\Queue\QueueManager; -use Illuminate\Contracts\Http\Kernel; use Swoole\Http\Server as HttpServer; use Illuminate\Support\ServiceProvider; -use SwooleTW\Http\Middleware\AccessLog; use SwooleTW\Http\Server\Facades\Server; use Illuminate\Database\DatabaseManager; use SwooleTW\Http\Coroutine\MySqlConnection; @@ -62,11 +60,18 @@ public function register() abstract protected function registerManager(); /** - * Boot routes. + * Boot websocket routes. * * @return void */ - abstract protected function bootRoutes(); + abstract protected function bootWebsocketRoutes(); + + /** + * Register access log middleware to container. + * + * @return void + */ + abstract protected function pushAccessLogMiddleware(); /** * Boot the service provider. @@ -88,7 +93,7 @@ public function boot() } if ($config->get('swoole_http.server.access_log')) { - $this->app->make(Kernel::class)->pushMiddleware(AccessLog::class); + $this->pushAccessLogMiddleware(); } } diff --git a/src/LaravelServiceProvider.php b/src/LaravelServiceProvider.php index d21b26f4..33c56c6f 100644 --- a/src/LaravelServiceProvider.php +++ b/src/LaravelServiceProvider.php @@ -3,6 +3,8 @@ namespace SwooleTW\Http; use SwooleTW\Http\Server\Manager; +use Illuminate\Contracts\Http\Kernel; +use SwooleTW\Http\Middleware\AccessLog; /** * @codeCoverageIgnore @@ -24,12 +26,23 @@ protected function registerManager() } /** - * Boot routes. + * Boot websocket routes. * * @return void */ - protected function bootRoutes() + protected function bootWebsocketRoutes() + { { require __DIR__ . '/../routes/laravel_routes.php'; } + + /** + * Register access log middleware to container. + * + * @return void + */ + protected function pushAccessLogMiddleware() + { + $this->app->make(Kernel::class)->pushMiddleware(AccessLog::class); + } } diff --git a/src/LumenServiceProvider.php b/src/LumenServiceProvider.php index e29f948c..7e647213 100644 --- a/src/LumenServiceProvider.php +++ b/src/LumenServiceProvider.php @@ -3,6 +3,7 @@ namespace SwooleTW\Http; use SwooleTW\Http\Server\Manager; +use SwooleTW\Http\Middleware\AccessLog; /** * @codeCoverageIgnore @@ -24,14 +25,15 @@ protected function registerManager() } /** - * Boot routes. + * Boot websocket routes. * * @return void */ - protected function bootRoutes() + protected function bootWebsocketRoutes() { $app = $this->app; + // router only exists after lumen 5.5 if (property_exists($app, 'router')) { $app->router->group(['namespace' => 'SwooleTW\Http\Controllers'], function ($app) { require __DIR__ . '/../routes/lumen_routes.php'; @@ -42,4 +44,14 @@ protected function bootRoutes() }); } } + + /** + * Register access log middleware to container. + * + * @return void + */ + protected function pushAccessLogMiddleware() + { + $this->app->middleware(AccessLog::class); + } } From c23a573c9fe323185c3259b0a10af66b7fa3fd91 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Thu, 7 Mar 2019 00:45:05 +0800 Subject: [PATCH 079/161] fix syntax error --- src/LaravelServiceProvider.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/LaravelServiceProvider.php b/src/LaravelServiceProvider.php index 33c56c6f..3f58e2ca 100644 --- a/src/LaravelServiceProvider.php +++ b/src/LaravelServiceProvider.php @@ -31,7 +31,6 @@ protected function registerManager() * @return void */ protected function bootWebsocketRoutes() - { { require __DIR__ . '/../routes/laravel_routes.php'; } From ad537b589ca2ea170b89df6bd54303a9979c69d5 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Thu, 7 Mar 2019 01:43:16 +0800 Subject: [PATCH 080/161] require vlucas/phpdotenv --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 69c534aa..e6d3fe61 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,8 @@ "illuminate/contracts": "~5.4", "illuminate/http": "~5.4", "illuminate/support": "~5.4", - "predis/predis": "^1.1" + "predis/predis": "^1.1", + "vlucas/phpdotenv": "^3.3" }, "require-dev": { "laravel/lumen-framework": "~5.4", From 4549f59db1a4c6a3e4f9575aac90fcf622b87298 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Thu, 7 Mar 2019 01:53:23 +0800 Subject: [PATCH 081/161] Revert "require vlucas/phpdotenv" This reverts commit ad537b589ca2ea170b89df6bd54303a9979c69d5. --- composer.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/composer.json b/composer.json index e6d3fe61..69c534aa 100644 --- a/composer.json +++ b/composer.json @@ -26,8 +26,7 @@ "illuminate/contracts": "~5.4", "illuminate/http": "~5.4", "illuminate/support": "~5.4", - "predis/predis": "^1.1", - "vlucas/phpdotenv": "^3.3" + "predis/predis": "^1.1" }, "require-dev": { "laravel/lumen-framework": "~5.4", From 9783f93dc708789a77f9133a485ce2e58a084e40 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Thu, 7 Mar 2019 09:55:48 +0800 Subject: [PATCH 082/161] fix HttpServiceProvider for bootWebsocketRoutes --- src/HttpServiceProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HttpServiceProvider.php b/src/HttpServiceProvider.php index 23a7caa3..573c5201 100644 --- a/src/HttpServiceProvider.php +++ b/src/HttpServiceProvider.php @@ -89,7 +89,7 @@ public function boot() $config = $this->app->make('config'); if ($config->get('swoole_http.websocket.enabled')) { - $this->bootRoutes(); + $this->bootWebsocketRoutes(); } if ($config->get('swoole_http.server.access_log')) { From fa965b77e2f87eedddaf25740d7ac12e04983d3a Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Thu, 7 Mar 2019 09:56:35 +0800 Subject: [PATCH 083/161] make compatible for dotenv 3 --- copy_versioned_files.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/copy_versioned_files.php b/copy_versioned_files.php index 50d9393a..f4f0b718 100644 --- a/copy_versioned_files.php +++ b/copy_versioned_files.php @@ -2,12 +2,18 @@ require __DIR__.'/vendor/autoload.php'; -use SwooleTW\Http\Coroutine\Connectors\ConnectorFactory; use SwooleTW\Http\Helpers\FW; use SwooleTW\Http\Task\QueueFactory; +use SwooleTW\Http\Coroutine\Connectors\ConnectorFactory; + +try { + $framework = ucfirst(FW::current()); + $version = FW::version(); +} catch (Throwable $e) { + echo "No files were generated.\n"; + die; +} -$version = FW::version(); -$framework = ucfirst(FW::current()); $color = "\033[0;32m"; $noColor = "\033[0m"; $stubs = []; From 06ad668b7fadf4f5b0b5969665fc1b632b726a1d Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sat, 9 Mar 2019 14:22:01 +0800 Subject: [PATCH 084/161] fix namespace for analyzing if an fd is a websocket payload in onClose event --- src/Concerns/InteractsWithWebsocket.php | 5 +++-- src/Websocket/Pusher.php | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Concerns/InteractsWithWebsocket.php b/src/Concerns/InteractsWithWebsocket.php index 19485ec6..1e945138 100644 --- a/src/Concerns/InteractsWithWebsocket.php +++ b/src/Concerns/InteractsWithWebsocket.php @@ -12,6 +12,7 @@ use SwooleTW\Http\Server\Facades\Server; use SwooleTW\Http\Websocket\HandlerContract; use Illuminate\Contracts\Container\Container; +use Swoole\WebSocket\Server as WebsocketServer; use SwooleTW\Http\Websocket\Rooms\RoomContract; use SwooleTW\Http\Exceptions\WebsocketNotSetInConfigException; @@ -129,7 +130,7 @@ public function onMessage($server, $frame) */ public function onClose($server, $fd, $reactorId) { - if (! $this->isServerWebsocket($fd) || ! $server instanceof Websocket) { + if (! $this->isServerWebsocket($fd) || ! $server instanceof WebsocketServer) { return; } @@ -229,7 +230,7 @@ protected function prepareWebsocket() */ protected function isServerWebsocket(int $fd): bool { - return $this->container->make(Server::class) + return (bool) $this->container->make(Server::class) ->connection_info($fd)['websocket_status'] ?? false; } diff --git a/src/Websocket/Pusher.php b/src/Websocket/Pusher.php index b63b1b7c..e31eafb5 100644 --- a/src/Websocket/Pusher.php +++ b/src/Websocket/Pusher.php @@ -221,7 +221,7 @@ public function shouldBroadcast(): bool */ public function isServerWebsocket(int $fd): bool { - return $this->server->connection_info($fd)['websocket_status'] ?? false; + return (bool) $this->server->connection_info($fd)['websocket_status'] ?? false; } /** From 4d28803a8c351e6d92c036dfa7f8eb123f4ea8a3 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sat, 9 Mar 2019 15:40:00 +0800 Subject: [PATCH 085/161] fix shouldPushToDescriptor in pusher --- src/Websocket/Pusher.php | 7 +++++-- tests/Websocket/PusherTest.php | 14 +++++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/Websocket/Pusher.php b/src/Websocket/Pusher.php index e31eafb5..cad25f47 100644 --- a/src/Websocket/Pusher.php +++ b/src/Websocket/Pusher.php @@ -245,8 +245,11 @@ protected function getWebsocketConnections(): array */ public function shouldPushToDescriptor(int $fd): bool { - return $this->server->exist($fd) - && ($this->broadcast && $this->sender !== (int) $fd); + if (! $this->server->exist($fd)) { + return false; + } + + return $this->broadcast ? $this->sender !== (int) $fd : true; } /** diff --git a/tests/Websocket/PusherTest.php b/tests/Websocket/PusherTest.php index 0d97a0b7..0985527f 100644 --- a/tests/Websocket/PusherTest.php +++ b/tests/Websocket/PusherTest.php @@ -115,7 +115,7 @@ public function testShouldPushToDescriptor() $server = m::mock(Server::class); $server->shouldReceive('exist') ->with($fd = 1) - ->twice() + ->times(3) ->andReturn(true); $pusher = Pusher::make([ @@ -141,5 +141,17 @@ public function testShouldPushToDescriptor() ], $server); $this->assertFalse($pusher->shouldPushToDescriptor($fd)); + + $pusher = Pusher::make([ + 'opcode' => 1, + 'sender' => 1, + 'fds' => [], + 'broadcast' => false, + 'assigned' => false, + 'event' => 'event', + 'message' => 'message' + ], $server); + + $this->assertTrue($pusher->shouldPushToDescriptor($fd)); } } From 66d64db1916c49422e53d47a9ee94c175832f6c5 Mon Sep 17 00:00:00 2001 From: kwdwkiss Date: Fri, 22 Mar 2019 09:23:01 +0800 Subject: [PATCH 086/161] fix HttpServiceProvider::configureSwooleServer --- src/HttpServiceProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HttpServiceProvider.php b/src/HttpServiceProvider.php index 573c5201..f2dfb2c8 100644 --- a/src/HttpServiceProvider.php +++ b/src/HttpServiceProvider.php @@ -150,7 +150,7 @@ protected function configureSwooleServer() // only enable task worker in websocket mode and for queue driver if ($config->get('queue.default') !== 'swoole' && ! $this->isWebsocket) { - unset($config['task_worker_num']); + unset($options['task_worker_num']); } static::$server->set($options); From cd4ddceb2889254e5dd8a1cf2524d91fd678d4bd Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Tue, 26 Mar 2019 01:05:32 +0800 Subject: [PATCH 087/161] drop support for Laravel 5.4 and require swoole 4.3.1 --- .travis.yml | 8 +++----- routes/lumen_routes.php | 9 ++------- src/Commands/HttpServerCommand.php | 13 +++++++------ src/Helpers/FW.php | 2 +- src/LumenServiceProvider.php | 12 ++---------- 5 files changed, 15 insertions(+), 29 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7275047..f8694e08 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,24 +4,22 @@ sudo: false matrix: include: - - php: 7.2 - env: FRAMEWORK_VERSION=laravel/framework:5.4.* - php: 7.2 env: FRAMEWORK_VERSION=laravel/framework:5.5.* - php: 7.2 env: FRAMEWORK_VERSION=laravel/framework:5.6.* - php: 7.2 env: FRAMEWORK_VERSION=laravel/framework:5.7.* - # - php: 7.2 - # env: FRAMEWORK_VERSION=laravel/framework:5.8.* - php: 7.2 - env: FRAMEWORK_VERSION=laravel/lumen-framework:5.4.* + env: FRAMEWORK_VERSION=laravel/framework:5.8.* - php: 7.2 env: FRAMEWORK_VERSION=laravel/lumen-framework:5.5.* - php: 7.2 env: FRAMEWORK_VERSION=laravel/lumen-framework:5.6.* - php: 7.2 env: FRAMEWORK_VERSION=laravel/lumen-framework:5.7.* + - php: 7.2 + env: FRAMEWORK_VERSION=laravel/lumen-framework:5.8.* before_install: - printf "\n" | pecl install swoole diff --git a/routes/lumen_routes.php b/routes/lumen_routes.php index 80455aab..1f753a21 100644 --- a/routes/lumen_routes.php +++ b/routes/lumen_routes.php @@ -11,10 +11,5 @@ | */ -$app->get('socket.io', [ - 'as' => 'io.get', 'uses' => 'SocketIOController@upgrade', -]); - -$app->post('socket.io', [ - 'as' => 'io.post', 'uses' => 'SocketIOController@reject', -]); +$router->get('socket.io', ['uses' => 'SocketIOController@upgrade']); +$router->post('socket.io', ['uses' => 'SocketIOController@reject']); diff --git a/src/Commands/HttpServerCommand.php b/src/Commands/HttpServerCommand.php index 2d1ab105..26f85908 100644 --- a/src/Commands/HttpServerCommand.php +++ b/src/Commands/HttpServerCommand.php @@ -5,13 +5,14 @@ use Throwable; use Swoole\Process; use Illuminate\Support\Arr; +use SwooleTW\Http\Helpers\OS; use Illuminate\Console\Command; use SwooleTW\Http\Server\Manager; use Illuminate\Console\OutputStyle; use SwooleTW\Http\HotReload\FSEvent; -use SwooleTW\Http\Server\AccessOutput; use SwooleTW\Http\HotReload\FSOutput; use SwooleTW\Http\HotReload\FSProcess; +use SwooleTW\Http\Server\AccessOutput; use SwooleTW\Http\Middleware\AccessLog; use SwooleTW\Http\Server\Facades\Server; use Illuminate\Contracts\Container\Container; @@ -372,20 +373,20 @@ protected function isDaemon(): bool */ protected function checkEnvironment() { - if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { - $this->error("Swoole extension doesn't support Windows OS yet."); + if (OS::is(OS::WIN)) { + $this->error('Swoole extension doesn\'t support Windows OS.'); exit(1); } if (! extension_loaded('swoole')) { - $this->error("Can't detect Swoole extension installed."); + $this->error('Can\'t detect Swoole extension installed.'); exit(1); } - if (! version_compare(swoole_version(), '4.0.0', 'ge')) { - $this->error("Your Swoole version must be higher than 4.0 to use coroutine."); + if (! version_compare(swoole_version(), '4.3.1', 'ge')) { + $this->error('Your Swoole version must be higher than `4.3.1`.'); exit(1); } diff --git a/src/Helpers/FW.php b/src/Helpers/FW.php index 61ae34c3..818e5189 100644 --- a/src/Helpers/FW.php +++ b/src/Helpers/FW.php @@ -47,7 +47,7 @@ final class FW */ public static function is(string ...$types): bool { - return \in_array(static::current(), $types, true); + return in_array(static::current(), $types, true); } /** diff --git a/src/LumenServiceProvider.php b/src/LumenServiceProvider.php index 7e647213..eab77c83 100644 --- a/src/LumenServiceProvider.php +++ b/src/LumenServiceProvider.php @@ -31,18 +31,10 @@ protected function registerManager() */ protected function bootWebsocketRoutes() { - $app = $this->app; - - // router only exists after lumen 5.5 - if (property_exists($app, 'router')) { - $app->router->group(['namespace' => 'SwooleTW\Http\Controllers'], function ($app) { - require __DIR__ . '/../routes/lumen_routes.php'; - }); - } else { - $app->group(['namespace' => 'App\Http\Controllers'], function ($app) { + $this->app->router + ->group(['namespace' => 'SwooleTW\Http\Controllers'], function ($router) { require __DIR__ . '/../routes/lumen_routes.php'; }); - } } /** From b1a3f331513bc027e6535e30b8d7057fea009bac Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Tue, 26 Mar 2019 01:09:21 +0800 Subject: [PATCH 088/161] make pusher support swoole 4.3 --- src/Websocket/Pusher.php | 18 +++--------------- tests/Server/ManagerTest.php | 2 +- tests/Websocket/PusherTest.php | 16 ++++------------ 3 files changed, 8 insertions(+), 28 deletions(-) diff --git a/src/Websocket/Pusher.php b/src/Websocket/Pusher.php index cad25f47..7f5b0c4f 100644 --- a/src/Websocket/Pusher.php +++ b/src/Websocket/Pusher.php @@ -212,18 +212,6 @@ public function shouldBroadcast(): bool return $this->broadcast && empty($this->descriptors) && ! $this->assigned; } - /** - * Check if it's a websocket fd. - * - * @param int $fd - * - * @return bool - */ - public function isServerWebsocket(int $fd): bool - { - return (bool) $this->server->connection_info($fd)['websocket_status'] ?? false; - } - /** * Returns all descriptors that are websocket * @@ -234,7 +222,7 @@ public function isServerWebsocket(int $fd): bool protected function getWebsocketConnections(): array { return array_filter(iterator_to_array($this->server->connections), function ($fd) { - return $this->isServerWebsocket($fd); + return $this->server->isEstablished($fd); }); } @@ -245,7 +233,7 @@ protected function getWebsocketConnections(): array */ public function shouldPushToDescriptor(int $fd): bool { - if (! $this->server->exist($fd)) { + if (! $this->server->isEstablished($fd)) { return false; } @@ -278,4 +266,4 @@ public function push($payload): void } } } -} \ No newline at end of file +} diff --git a/tests/Server/ManagerTest.php b/tests/Server/ManagerTest.php index add08370..c5d47497 100644 --- a/tests/Server/ManagerTest.php +++ b/tests/Server/ManagerTest.php @@ -565,7 +565,7 @@ public function testPushMessage() ->andReturn(false); $server = m::mock('server'); - $server->shouldReceive('exist') + $server->shouldReceive('isEstablished') ->andReturn(true); $server->shouldReceive('push') ->twice(); diff --git a/tests/Websocket/PusherTest.php b/tests/Websocket/PusherTest.php index 0985527f..1913592c 100644 --- a/tests/Websocket/PusherTest.php +++ b/tests/Websocket/PusherTest.php @@ -89,31 +89,23 @@ public function testHasDescriptor() public function testShouldBroadcast() { - $server = m::mock(Server::class); - $server->shouldReceive('connection_info') - ->with($fd = 1) - ->once() - ->andReturn([ - 'websocket_status' => true - ]); - $pusher = Pusher::make([ 'opcode' => 1, - 'sender' => 3, + 'sender' => 1, 'fds' => [], 'broadcast' => true, 'assigned' => false, 'event' => 'event', 'message' => 'message' - ], $server); + ], null); - $this->assertTrue($pusher->isServerWebsocket($fd)); + $this->assertTrue($pusher->shouldBroadcast()); } public function testShouldPushToDescriptor() { $server = m::mock(Server::class); - $server->shouldReceive('exist') + $server->shouldReceive('isEstablished') ->with($fd = 1) ->times(3) ->andReturn(true); From 76b1ade6145ddb0c822403c464a8332a783c5547 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Tue, 26 Mar 2019 02:18:55 +0800 Subject: [PATCH 089/161] fix withApplication in lumen --- .travis.yml | 4 ++-- src/Concerns/WithApplication.php | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index f8694e08..d6af8a0c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,8 +18,8 @@ matrix: env: FRAMEWORK_VERSION=laravel/lumen-framework:5.6.* - php: 7.2 env: FRAMEWORK_VERSION=laravel/lumen-framework:5.7.* - - php: 7.2 - env: FRAMEWORK_VERSION=laravel/lumen-framework:5.8.* + # - php: 7.2 + # env: FRAMEWORK_VERSION=laravel/lumen-framework:5.8.* before_install: - printf "\n" | pecl install swoole diff --git a/src/Concerns/WithApplication.php b/src/Concerns/WithApplication.php index a7e28906..8a09a1fb 100644 --- a/src/Concerns/WithApplication.php +++ b/src/Concerns/WithApplication.php @@ -36,9 +36,7 @@ protected function bootstrap() if (method_exists($this->app, 'boot')) { $this->app->boot(); } - if (is_null(Facade::getFacadeApplication())) { - $this->app->withFacades(); - } + $this->app->withFacades(); } $this->preResolveInstances(); From 59db45341338426876caa689e6a633c9a59e0398 Mon Sep 17 00:00:00 2001 From: Valeriu Vodnicear Date: Sun, 31 Mar 2019 01:15:35 +0200 Subject: [PATCH 090/161] change minimal version php and laravel --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0fc49176..ab57cdcb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Laravel-Swoole -![php-badge](https://img.shields.io/badge/php-%3E%3D%207.1-8892BF.svg) +![php-badge](https://img.shields.io/badge/php-%3E%3D%207.2-8892BF.svg) [![packagist-badge](https://img.shields.io/packagist/v/swooletw/laravel-swoole.svg)](https://packagist.org/packages/swooletw/laravel-swoole) [![Total Downloads](https://poser.pugx.org/swooletw/laravel-swoole/downloads)](https://packagist.org/packages/swooletw/laravel-swoole) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/swooletw/laravel-swoole/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/swooletw/laravel-swoole/?branch=master) @@ -12,7 +12,7 @@ This package provides a high performance HTTP server to speed up your Laravel/Lu | PHP | Laravel | Lumen | Swoole | |:-------:|:-------:|:-----:|:-------:| -| >=7.2 | ~5.4 | ~5.4 | >=4.0.0 | +| >=7.2 | ~5.8 | ~5.4 | >=4.0.0 | ## Features From 04ffc0506b0294b9c94a1b8972f01deba42e4131 Mon Sep 17 00:00:00 2001 From: Muhammad Abdul Azim <42019012+mabdulazim@users.noreply.github.com> Date: Sun, 31 Mar 2019 13:38:11 +0200 Subject: [PATCH 091/161] Update message attribute datatype in Pusher.php update message attribute datatype to mixed rather than string to send json object as the data --- src/Websocket/Pusher.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Websocket/Pusher.php b/src/Websocket/Pusher.php index cad25f47..a6ec1880 100644 --- a/src/Websocket/Pusher.php +++ b/src/Websocket/Pusher.php @@ -45,7 +45,7 @@ class Pusher protected $event; /** - * @var string|null + * @var mixed|null */ protected $message; @@ -58,7 +58,7 @@ class Pusher * @param bool $broadcast * @param bool $assigned * @param string $event - * @param string|null $message + * @param mixed|null $message * @param \Swoole\Websocket\Server */ protected function __construct( @@ -68,7 +68,7 @@ protected function __construct( bool $broadcast, bool $assigned, string $event, - string $message = null, + $message = null, $server ) { @@ -189,9 +189,9 @@ public function getEvent(): string } /** - * @return string|null + * @return mixed|null */ - public function getMessage(): ?string + public function getMessage() { return $this->message; } @@ -278,4 +278,4 @@ public function push($payload): void } } } -} \ No newline at end of file +} From cbf0f6e72e93008acc4dc46a6909a7600e9ab0fb Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Sat, 6 Apr 2019 22:04:02 +1100 Subject: [PATCH 092/161] add dump Helpers --- src/Helpers/Dump.php | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/Helpers/Dump.php diff --git a/src/Helpers/Dump.php b/src/Helpers/Dump.php new file mode 100644 index 00000000..51119ace --- /dev/null +++ b/src/Helpers/Dump.php @@ -0,0 +1,35 @@ +dump($cloner->cloneVar($arg)); + } + + return true; + } +} \ No newline at end of file From 0bcc42caa73ed42301349b94e803247d76d51de6 Mon Sep 17 00:00:00 2001 From: Sascha-Oliver Prolic Date: Tue, 9 Apr 2019 11:39:43 +0800 Subject: [PATCH 093/161] Fix Server Manager `SwooleTaskJob` has a `fire()` method, not a `dispatch()` method. --- src/Server/Manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 4258a707..634e4b81 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -271,7 +271,7 @@ public function onTask($server, $taskId, $srcWorkerId, $data) $this->pushMessage($server, $data['data']); // push async task to queue } elseif ($this->isAsyncTaskPayload($data)) { - (new SwooleTaskJob($this->container, $server, $data, $taskId, $srcWorkerId))->dispatch(); + (new SwooleTaskJob($this->container, $server, $data, $taskId, $srcWorkerId))->fire(); } } catch (Throwable $e) { $this->logServerError($e); From 8b74ab90543504ef351d0c2344d7f6780f3d6c31 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sat, 20 Apr 2019 22:29:50 +0800 Subject: [PATCH 094/161] enhance dumper --- src/Helpers/Dump.php | 35 ----------------------------------- src/Helpers/Dumper.php | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 35 deletions(-) delete mode 100644 src/Helpers/Dump.php create mode 100644 src/Helpers/Dumper.php diff --git a/src/Helpers/Dump.php b/src/Helpers/Dump.php deleted file mode 100644 index 51119ace..00000000 --- a/src/Helpers/Dump.php +++ /dev/null @@ -1,35 +0,0 @@ -dump($cloner->cloneVar($arg)); - } - - return true; - } -} \ No newline at end of file diff --git a/src/Helpers/Dumper.php b/src/Helpers/Dumper.php new file mode 100644 index 00000000..c4ffb68b --- /dev/null +++ b/src/Helpers/Dumper.php @@ -0,0 +1,38 @@ +dump( + static::$cloner->cloneVar($arg) + ); + } + + return true; + } + + public static function getDumper() + { + $dumper = defined('IN_PHPUNIT') || ! config('swoole_http.ob_output') + ? CliDumper::class + : HtmlDumper::class; + + return new $dumper; + } +} From 8b97ba89194d09d1dcd4962ae0af2c1afaf7dee1 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sat, 20 Apr 2019 22:49:08 +0800 Subject: [PATCH 095/161] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ab57cdcb..fa945604 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This package provides a high performance HTTP server to speed up your Laravel/Lu | PHP | Laravel | Lumen | Swoole | |:-------:|:-------:|:-----:|:-------:| -| >=7.2 | ~5.8 | ~5.4 | >=4.0.0 | +| >=7.2 | ~5.8 | ~5.5 | >=4.3.1 | ## Features From acc3b7e9e5bf3a89364d7d4a2363a728d1ed4141 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sat, 20 Apr 2019 22:49:26 +0800 Subject: [PATCH 096/161] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fa945604..fc49d23e 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This package provides a high performance HTTP server to speed up your Laravel/Lu | PHP | Laravel | Lumen | Swoole | |:-------:|:-------:|:-----:|:-------:| -| >=7.2 | ~5.8 | ~5.5 | >=4.3.1 | +| >=7.2 | ~5.5 | ~5.5 | >=4.3.1 | ## Features From 5b2b08a45eeb99e32ae66a0b362dc3916164ad31 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sat, 20 Apr 2019 22:54:10 +0800 Subject: [PATCH 097/161] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fc49d23e..1a244625 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This package provides a high performance HTTP server to speed up your Laravel/Lu | PHP | Laravel | Lumen | Swoole | |:-------:|:-------:|:-----:|:-------:| -| >=7.2 | ~5.5 | ~5.5 | >=4.3.1 | +| >=7.2 | >=5.5 | >=5.5 | >=4.3.1 | ## Features From 9abe23f50890087ccb7167651ed0c58daa6bbca1 Mon Sep 17 00:00:00 2001 From: Bill Li Date: Wed, 8 May 2019 21:26:17 +0800 Subject: [PATCH 098/161] Fix default options empty mysql user,password --- src/Coroutine/PDO.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Coroutine/PDO.php b/src/Coroutine/PDO.php index bf51a519..2ee646f2 100644 --- a/src/Coroutine/PDO.php +++ b/src/Coroutine/PDO.php @@ -122,7 +122,7 @@ protected function getOptions($dsn, $username, $password, $driverOptions) } } - return array_merge($configuredOptions, static::$options); + return array_merge(static::$options, $configuredOptions); } /** From 0cb518c17d15a0e5eec6c7929ad1ff6e858a9dac Mon Sep 17 00:00:00 2001 From: Bill li Date: Mon, 13 May 2019 08:49:20 +0800 Subject: [PATCH 099/161] pid manager. --- src/Commands/HttpServerCommand.php | 115 ++++++++++++----------------- src/HttpServiceProvider.php | 29 ++++++-- src/LaravelServiceProvider.php | 5 +- src/LumenServiceProvider.php | 5 +- src/Server/Manager.php | 51 ++++--------- src/Server/PidManager.php | 72 ++++++++++++++++++ src/Server/PidManagerFactory.php | 17 +++++ 7 files changed, 180 insertions(+), 114 deletions(-) create mode 100644 src/Server/PidManager.php create mode 100644 src/Server/PidManagerFactory.php diff --git a/src/Commands/HttpServerCommand.php b/src/Commands/HttpServerCommand.php index 26f85908..3f199317 100644 --- a/src/Commands/HttpServerCommand.php +++ b/src/Commands/HttpServerCommand.php @@ -13,6 +13,7 @@ use SwooleTW\Http\HotReload\FSOutput; use SwooleTW\Http\HotReload\FSProcess; use SwooleTW\Http\Server\AccessOutput; +use SwooleTW\Http\Server\PidManager; use SwooleTW\Http\Middleware\AccessLog; use SwooleTW\Http\Server\Facades\Server; use Illuminate\Contracts\Container\Container; @@ -59,6 +60,25 @@ class HttpServerCommand extends Command */ protected $config; + /** + * A manager to handle pid about the application. + * + * @var PidManager + */ + protected $pidManager; + + /** + * Create a an new HttpServerCommand instance. + * + * @param PidManager $pidManager + */ + public function __construct(PidManager $pidManager) + { + parent::__construct(); + + $this->pidManager = $pidManager; + } + /** * Execute the console command. * @@ -93,7 +113,7 @@ protected function runAction() */ protected function start() { - if ($this->isRunning($this->getCurrentPid())) { + if ($this->isRunning()) { $this->error('Failed! swoole_http_server process is already running.'); return; @@ -132,9 +152,7 @@ protected function start() */ protected function stop() { - $pid = $this->getCurrentPid(); - - if (! $this->isRunning($pid)) { + if (! $this->isRunning()) { $this->error("Failed! There is no swoole_http_server process running."); return; @@ -142,7 +160,7 @@ protected function stop() $this->info('Stopping swoole http server...'); - $isRunning = $this->killProcess($pid, SIGTERM, 15); + $isRunning = $this->killProcess(SIGTERM, 15); if ($isRunning) { $this->error('Unable to stop the swoole_http_server process.'); @@ -152,7 +170,7 @@ protected function stop() // I don't known why Swoole didn't trigger "onShutdown" after sending SIGTERM. // So we should manually remove the pid file. - $this->removePidFile(); + $this->pidManager->delete(); $this->info('> success'); } @@ -162,9 +180,7 @@ protected function stop() */ protected function restart() { - $pid = $this->getCurrentPid(); - - if ($this->isRunning($pid)) { + if ($this->isRunning()) { $this->stop(); } @@ -176,9 +192,7 @@ protected function restart() */ protected function reload() { - $pid = $this->getCurrentPid(); - - if (! $this->isRunning($pid)) { + if (! $this->isRunning()) { $this->error("Failed! There is no swoole_http_server process running."); return; @@ -186,9 +200,7 @@ protected function reload() $this->info('Reloading swoole_http_server...'); - $isRunning = $this->killProcess($pid, SIGUSR1); - - if (! $isRunning) { + if (! $this->killProcess(SIGUSR1)) { $this->error('> failure'); return; @@ -210,8 +222,7 @@ protected function infos() */ protected function showInfos() { - $pid = $this->getCurrentPid(); - $isRunning = $this->isRunning($pid); + $isRunning = $this->isRunning(); $host = Arr::get($this->config, 'server.host'); $port = Arr::get($this->config, 'server.port'); $reactorNum = Arr::get($this->config, 'server.options.reactor_num'); @@ -231,7 +242,7 @@ protected function showInfos() ['Worker Num', $workerNum], ['Task Worker Num', $isWebsocket ? $taskWorkerNum : 0], ['Websocket Mode', $isWebsocket ? 'On' : 'Off'], - ['PID', $isRunning ? $pid : 'None'], + ['PID', $isRunning ? implode(', ', $this->pidManager->read()) : 'None'], ['Log Path', $logFile], ]; @@ -281,37 +292,45 @@ protected function getHotReloadProcess($server) * * @return bool */ - protected function isRunning($pid) + public function isRunning() { - if (! $pid) { + $pids = $this->pidManager->read(); + + if ([] === $pids) { return false; } - try { - return Process::kill($pid, 0); - } catch (Throwable $e) { - return false; + [$masterPid, $managerPid] = $pids; + + if ($managerPid) { + // Swoole process mode + return $masterPid && $managerPid && Process::kill((int) $managerPid, 0); } + + // Swoole base mode, no manager process + return $masterPid && Process::kill((int) $masterPid, 0); } /** * Kill process. * - * @param int $pid * @param int $sig * @param int $wait * * @return bool */ - protected function killProcess($pid, $sig, $wait = 0) + protected function killProcess($sig, $wait = 0) { - Process::kill($pid, $sig); + Process::kill( + Arr::first($this->pidManager->read()), + $sig + ); if ($wait) { $start = time(); do { - if (! $this->isRunning($pid)) { + if (! $this->isRunning()) { break; } @@ -319,45 +338,7 @@ protected function killProcess($pid, $sig, $wait = 0) } while (time() < $start + $wait); } - return $this->isRunning($pid); - } - - /** - * Get pid. - * - * @return int|null - */ - protected function getCurrentPid() - { - if ($this->currentPid) { - return $this->currentPid; - } - - $path = $this->getPidPath(); - - return $this->currentPid = file_exists($path) - ? (int) file_get_contents($path) ?? $this->removePidFile() - : null; - } - - /** - * Get Pid file path. - * - * @return string - */ - protected function getPidPath() - { - return Arr::get($this->config, 'server.options.pid_file', storage_path('logs/swoole.pid')); - } - - /** - * Remove Pid file. - */ - protected function removePidFile() - { - if (file_exists($this->getPidPath())) { - unlink($this->getPidPath()); - } + return $this->isRunning(); } /** diff --git a/src/HttpServiceProvider.php b/src/HttpServiceProvider.php index f2dfb2c8..3191aa2d 100644 --- a/src/HttpServiceProvider.php +++ b/src/HttpServiceProvider.php @@ -2,17 +2,19 @@ namespace SwooleTW\Http; -use SwooleTW\Http\Helpers\FW; +use Illuminate\Database\DatabaseManager; use Illuminate\Queue\QueueManager; -use Swoole\Http\Server as HttpServer; use Illuminate\Support\ServiceProvider; -use SwooleTW\Http\Server\Facades\Server; -use Illuminate\Database\DatabaseManager; -use SwooleTW\Http\Coroutine\MySqlConnection; use SwooleTW\Http\Commands\HttpServerCommand; -use Swoole\Websocket\Server as WebsocketServer; -use SwooleTW\Http\Task\Connectors\SwooleTaskConnector; use SwooleTW\Http\Coroutine\Connectors\ConnectorFactory; +use SwooleTW\Http\Coroutine\MySqlConnection; +use SwooleTW\Http\Helpers\FW; +use SwooleTW\Http\Server\Facades\Server; +use SwooleTW\Http\Server\PidManager; +use SwooleTW\Http\Server\PidManagerFactory; +use SwooleTW\Http\Task\Connectors\SwooleTaskConnector; +use Swoole\Http\Server as HttpServer; +use Swoole\Websocket\Server as WebsocketServer; /** * @codeCoverageIgnore @@ -43,6 +45,7 @@ abstract class HttpServiceProvider extends ServiceProvider */ public function register() { + $this->registerPidManager(); $this->mergeConfigs(); $this->setIsWebsocket(); $this->registerServer(); @@ -106,6 +109,18 @@ protected function mergeConfigs() $this->mergeConfigFrom(__DIR__ . '/../config/swoole_websocket.php', 'swoole_websocket'); } + /** + * Register pid manager. + * + * @return void + */ + protected function registerPidManager(): void + { + $this->app->singleton(PidManager::class, function() { + return call_user_func(new PidManagerFactory, $this->app); + }); + } + /** * Set isWebsocket. */ diff --git a/src/LaravelServiceProvider.php b/src/LaravelServiceProvider.php index 3f58e2ca..5bab7cd9 100644 --- a/src/LaravelServiceProvider.php +++ b/src/LaravelServiceProvider.php @@ -2,9 +2,10 @@ namespace SwooleTW\Http; -use SwooleTW\Http\Server\Manager; use Illuminate\Contracts\Http\Kernel; use SwooleTW\Http\Middleware\AccessLog; +use SwooleTW\Http\Server\Manager; +use SwooleTW\Http\Server\PidManager; /** * @codeCoverageIgnore @@ -19,7 +20,7 @@ class LaravelServiceProvider extends HttpServiceProvider protected function registerManager() { $this->app->singleton(Manager::class, function ($app) { - return new Manager($app, 'laravel'); + return new Manager($app, 'laravel', base_path(), $this->app[PidManager::class]); }); $this->app->alias(Manager::class, 'swoole.manager'); diff --git a/src/LumenServiceProvider.php b/src/LumenServiceProvider.php index eab77c83..bed2e340 100644 --- a/src/LumenServiceProvider.php +++ b/src/LumenServiceProvider.php @@ -2,8 +2,9 @@ namespace SwooleTW\Http; -use SwooleTW\Http\Server\Manager; use SwooleTW\Http\Middleware\AccessLog; +use SwooleTW\Http\Server\Manager; +use SwooleTW\Http\Server\PidManager; /** * @codeCoverageIgnore @@ -18,7 +19,7 @@ class LumenServiceProvider extends HttpServiceProvider protected function registerManager() { $this->app->singleton(Manager::class, function ($app) { - return new Manager($app, 'lumen'); + return new Manager($app, 'lumen', base_path(), $this->app[PidManager::class]); }); $this->app->alias(Manager::class, 'swoole.manager'); diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 634e4b81..5fa3dad0 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -41,6 +41,13 @@ class Manager */ protected $container; + /** + * A manager to handle pid about the application. + * + * @var PidManager + */ + protected $pidManager; + /** * @var string */ @@ -82,11 +89,12 @@ class Manager * * @throws \Exception */ - public function __construct(Container $container, $framework, $basePath = null) + public function __construct(Container $container, $framework, $basePath = null, PidManager $pidManager) { $this->container = $container; $this->setFramework($framework); $this->setBasepath($basePath); + $this->pidManager = $pidManager; $this->initialize(); } @@ -137,7 +145,10 @@ protected function setSwooleServerListeners() public function onStart() { $this->setProcessName('master process'); - $this->createPidFile(); + + $server = $this->container->make(Server::class); + + $this->pidManager->write($server->master_pid, $server->manager_pid); $this->container->make('events')->dispatch('swoole.start', func_get_args()); } @@ -150,6 +161,7 @@ public function onStart() public function onManagerStart() { $this->setProcessName('manager process'); + $this->container->make('events')->dispatch('swoole.managerStart', func_get_args()); } @@ -298,7 +310,7 @@ public function onFinish($server, $taskId, $data) */ public function onShutdown() { - $this->removePidFile(); + $this->pidManager->delete(); } /** @@ -327,39 +339,6 @@ protected function bindSandbox() $this->app->alias(Sandbox::class, 'swoole.sandbox'); } - /** - * Gets pid file path. - * - * @return string - */ - protected function getPidFile() - { - return $this->container->make('config')->get('swoole_http.server.options.pid_file'); - } - - /** - * Create pid file. - */ - protected function createPidFile() - { - $pidFile = $this->getPidFile(); - $pid = $this->container->make(Server::class)->master_pid; - - file_put_contents($pidFile, $pid); - } - - /** - * Remove pid file. - */ - protected function removePidFile() - { - $pidFile = $this->getPidFile(); - - if (file_exists($pidFile)) { - unlink($pidFile); - } - } - /** * Clear APC or OPCache. */ diff --git a/src/Server/PidManager.php b/src/Server/PidManager.php new file mode 100644 index 00000000..00a0a18a --- /dev/null +++ b/src/Server/PidManager.php @@ -0,0 +1,72 @@ +pidFile = $pidFile; + } + + /** + * Write master pid and manager pid to pid file + * + * @throws Exception\RuntimeException When $pidFile is not writable + */ + public function write(int $masterPid, int $managerPid): void + { + if (! is_writable($this->pidFile) && ! is_writable(dirname($this->pidFile))) { + throw new Exception\RuntimeException(sprintf('Pid file "%s" is not writable', $this->pidFile)); + } + + file_put_contents($this->pidFile, $masterPid . ',' . $managerPid); + } + + /** + * Read master pid and manager pid from pid file + * + * @return string[] { + * @var string $masterPid + * @var string $managerPid + * } + */ + public function read(): array + { + $pids = []; + + if (is_readable($this->pidFile)) { + $content = file_get_contents($this->pidFile); + $pids = explode(',', $content); + } + + return $pids; + } + + /** + * Gets pid file path. + * + * @return string + */ + public function file() + { + return $this->pidFile; + } + + /** + * Delete pid file + */ + public function delete(): bool + { + if (is_writable($this->pidFile)) { + return unlink($this->pidFile); + } + + return false; + } +} diff --git a/src/Server/PidManagerFactory.php b/src/Server/PidManagerFactory.php new file mode 100644 index 00000000..a0a851b5 --- /dev/null +++ b/src/Server/PidManagerFactory.php @@ -0,0 +1,17 @@ +get('config'); + + return new PidManager( + $config->get('swoole_http.server.options.pid_file') ?? sys_get_temp_dir() . '/ofcold-swoole.pid' + ); + } +} From 74e0e6b6c5bbfa9b3eb1ba08c459697714d47acd Mon Sep 17 00:00:00 2001 From: Bill Li Date: Mon, 13 May 2019 08:54:24 +0800 Subject: [PATCH 100/161] Update PidManagerFactory.php --- src/Server/PidManagerFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Server/PidManagerFactory.php b/src/Server/PidManagerFactory.php index a0a851b5..900db2b1 100644 --- a/src/Server/PidManagerFactory.php +++ b/src/Server/PidManagerFactory.php @@ -11,7 +11,7 @@ public function __invoke(ContainerInterface $container) : PidManager $config = $container->get('config'); return new PidManager( - $config->get('swoole_http.server.options.pid_file') ?? sys_get_temp_dir() . '/ofcold-swoole.pid' + $config->get('swoole_http.server.options.pid_file') ?? sys_get_temp_dir() . '/swoole.pid' ); } } From 62262ca730081cfbbecef43601098d3e0aa8e08c Mon Sep 17 00:00:00 2001 From: Bill Li Date: Mon, 13 May 2019 09:35:51 +0800 Subject: [PATCH 101/161] Update PidManager.php --- src/Server/PidManager.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Server/PidManager.php b/src/Server/PidManager.php index 00a0a18a..ec21a4c5 100644 --- a/src/Server/PidManager.php +++ b/src/Server/PidManager.php @@ -17,12 +17,12 @@ public function __construct(string $pidFile) /** * Write master pid and manager pid to pid file * - * @throws Exception\RuntimeException When $pidFile is not writable + * @throws \RuntimeException When $pidFile is not writable */ public function write(int $masterPid, int $managerPid): void { if (! is_writable($this->pidFile) && ! is_writable(dirname($this->pidFile))) { - throw new Exception\RuntimeException(sprintf('Pid file "%s" is not writable', $this->pidFile)); + throw new \RuntimeException(sprintf('Pid file "%s" is not writable', $this->pidFile)); } file_put_contents($this->pidFile, $masterPid . ',' . $managerPid); From e66900d24e308dba8a6538c1f6b75aae70b34014 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 26 May 2019 00:24:29 +0800 Subject: [PATCH 102/161] fix initialization for websocket room --- src/Concerns/InteractsWithWebsocket.php | 33 ++++++++++++++++--------- src/Websocket/Rooms/TableRoom.php | 6 ++--- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/Concerns/InteractsWithWebsocket.php b/src/Concerns/InteractsWithWebsocket.php index 1e945138..b51a450d 100644 --- a/src/Concerns/InteractsWithWebsocket.php +++ b/src/Concerns/InteractsWithWebsocket.php @@ -40,6 +40,11 @@ trait InteractsWithWebsocket */ protected $payloadParser; + /** + * @var SwooleTW\Http\Websocket\Rooms\RoomContract + */ + protected $websocketRoom; + /** * Websocket server events. * @@ -217,6 +222,7 @@ protected function prepareWebsocket() if ($isWebsocket) { $this->events = array_merge($this->events ?? [], $this->wsEvents); $this->isServerWebsocket = true; + $this->prepareWebsocketRoom(); $this->setPayloadParser(new $parser); } } @@ -250,6 +256,20 @@ protected function prepareWebsocketHandler() $this->setWebsocketHandler($this->app->make($handlerClass)); } + /** + * Prepare websocket room. + */ + protected function prepareWebsocketRoom() + { + $config = $this->container->make('config'); + $driver = $config->get('swoole_websocket.default'); + $websocketConfig = $config->get("swoole_websocket.settings.{$driver}"); + $className = $config->get("swoole_websocket.drivers.{$driver}"); + + $this->websocketRoom = new $className($websocketConfig); + $this->websocketRoom->prepare(); + } + /** * Set websocket handler. * @@ -290,17 +310,8 @@ protected function createRoom(string $class, array $settings): RoomContract */ protected function bindRoom(): void { - $this->app->singleton(RoomContract::class, function (Container $container) { - $config = $container->make('config'); - $driver = $config->get('swoole_websocket.default'); - $settings = $config->get("swoole_websocket.settings.{$driver}"); - $className = $config->get("swoole_websocket.drivers.{$driver}"); - - // create room instance and initialize - $room = $this->createRoom($className, $settings); - $room->prepare(); - - return $room; + $this->app->singleton(RoomContract::class, function (Container $app) { + return $this->websocketRoom; }); $this->app->alias(RoomContract::class, 'swoole.room'); diff --git a/src/Websocket/Rooms/TableRoom.php b/src/Websocket/Rooms/TableRoom.php index 8b5e6fc7..ae9b0bfd 100644 --- a/src/Websocket/Rooms/TableRoom.php +++ b/src/Websocket/Rooms/TableRoom.php @@ -45,7 +45,7 @@ public function prepare(): RoomContract } /** - * Add multiple socket fds to a room. + * Add a socket fd to multiple rooms. * * @param int fd * @param array|string rooms @@ -72,7 +72,7 @@ public function add(int $fd, $roomNames) } /** - * Delete multiple socket fds from a room. + * Delete a socket fd from multiple rooms. * * @param int fd * @param array|string rooms @@ -95,7 +95,7 @@ public function delete(int $fd, $roomNames = []) $removeRooms[] = $room; } - $this->setRooms($fd, collect($allRooms)->diff($removeRooms)->values()->toArray()); + $this->setRooms($fd, array_values(array_diff($allRooms, $removeRooms))); } /** From 59ded9222cf515beb41cfdeb5e0dd827afb623b1 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 26 May 2019 00:26:38 +0800 Subject: [PATCH 103/161] fix typo in configuring server process type --- src/HttpServiceProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HttpServiceProvider.php b/src/HttpServiceProvider.php index f2dfb2c8..59aa50e4 100644 --- a/src/HttpServiceProvider.php +++ b/src/HttpServiceProvider.php @@ -135,7 +135,7 @@ protected function createSwooleServer() $host = $config->get('swoole_http.server.host'); $port = $config->get('swoole_http.server.port'); $socketType = $config->get('swoole_http.server.socket_type', SWOOLE_SOCK_TCP); - $processType = $config->get('swoole.http.server.process_type', SWOOLE_PROCESS); + $processType = $config->get('swoole_http.server.process_type', SWOOLE_PROCESS); static::$server = new $server($host, $port, $processType, $socketType); } From 04aa0ed908ad071e90c0e9343a01e28c4adacab8 Mon Sep 17 00:00:00 2001 From: Bill li Date: Sun, 26 May 2019 11:55:22 +0800 Subject: [PATCH 104/161] Add PidManagerFactoryTest test instance. --- tests/Server/PidManagerFactoryTest.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/Server/PidManagerFactoryTest.php diff --git a/tests/Server/PidManagerFactoryTest.php b/tests/Server/PidManagerFactoryTest.php new file mode 100644 index 00000000..067010ad --- /dev/null +++ b/tests/Server/PidManagerFactoryTest.php @@ -0,0 +1,20 @@ +prophesize(ContainerInterface::class)->reveal()); + + $this->assertInstanceOf(PidManager::class, $pidManager); + } +} From 0667437304f6a455a386d1f8b335ac379d056eb5 Mon Sep 17 00:00:00 2001 From: Bill li Date: Mon, 27 May 2019 10:32:49 +0800 Subject: [PATCH 105/161] Fix bugs. --- tests/Server/ManagerTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/Server/ManagerTest.php b/tests/Server/ManagerTest.php index c5d47497..c19e24cf 100644 --- a/tests/Server/ManagerTest.php +++ b/tests/Server/ManagerTest.php @@ -577,7 +577,9 @@ public function testPushMessage() protected function getManager($container = null, $framework = 'laravel', $path = '/') { - return new Manager($container ?: $this->getContainer(), $framework, $path); + $pidFacotry = (new PidManagerFactory)($this->getContainer()); + + return new Manager($container ?: $this->getContainer(), $framework, $path, $pidFacotry); } protected function getWebsocketManager($container = null) From f44764a2864e804643854b86c62c0ebc5391308d Mon Sep 17 00:00:00 2001 From: Bill li Date: Mon, 27 May 2019 11:13:10 +0800 Subject: [PATCH 106/161] fix SwooleTW\Http\Server\PidManagerFactory not found. --- tests/Server/ManagerTest.php | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/tests/Server/ManagerTest.php b/tests/Server/ManagerTest.php index c19e24cf..3875dbc1 100644 --- a/tests/Server/ManagerTest.php +++ b/tests/Server/ManagerTest.php @@ -2,29 +2,30 @@ namespace SwooleTW\Http\Tests\Server; +use Illuminate\Container\Container; +use Illuminate\Contracts\Config\Repository as ConfigContract; +use Illuminate\Contracts\Debug\ExceptionHandler; +use Illuminate\Support\Facades\Config; +use Laravel\Lumen\Exceptions\Handler; use Mockery as m; -use Swoole\Table; -use Swoole\Http\Request; -use Swoole\Http\Response; +use SwooleTW\Http\Server\Facades\Server; use SwooleTW\Http\Server\Manager; +use SwooleTW\Http\Server\PidManagerFactory; use SwooleTW\Http\Server\Sandbox; -use SwooleTW\Http\Tests\TestCase; -use Illuminate\Container\Container; -use SwooleTW\Http\Websocket\Parser; use SwooleTW\Http\Table\SwooleTable; -use Laravel\Lumen\Exceptions\Handler; -use Illuminate\Support\Facades\Config; -use SwooleTW\Http\Websocket\Websocket; -use SwooleTW\Http\Server\Facades\Server; +use SwooleTW\Http\Tests\TestCase; use SwooleTW\Http\Websocket\Facades\Pusher; +use SwooleTW\Http\Websocket\Facades\Websocket as WebsocketFacade; use SwooleTW\Http\Websocket\HandlerContract; -use SwooleTW\Http\Websocket\Rooms\TableRoom; +use SwooleTW\Http\Websocket\Parser; use SwooleTW\Http\Websocket\Rooms\RoomContract; -use Illuminate\Contracts\Debug\ExceptionHandler; +use SwooleTW\Http\Websocket\Rooms\TableRoom; use SwooleTW\Http\Websocket\SocketIO\SocketIOParser; use SwooleTW\Http\Websocket\SocketIO\WebsocketHandler; -use Illuminate\Contracts\Config\Repository as ConfigContract; -use SwooleTW\Http\Websocket\Facades\Websocket as WebsocketFacade; +use SwooleTW\Http\Websocket\Websocket; +use Swoole\Http\Request; +use Swoole\Http\Response; +use Swoole\Table; class ManagerTest extends TestCase { From f1adf651adbb4d13160b3de91bbb62928fb0888e Mon Sep 17 00:00:00 2001 From: Bill li Date: Mon, 27 May 2019 12:10:42 +0800 Subject: [PATCH 107/161] remove Psr\Container\ContainerInterface --- src/Server/PidManagerFactory.php | 8 ++------ tests/Server/PidManagerFactoryTest.php | 5 +---- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/Server/PidManagerFactory.php b/src/Server/PidManagerFactory.php index 900db2b1..b116471e 100644 --- a/src/Server/PidManagerFactory.php +++ b/src/Server/PidManagerFactory.php @@ -2,16 +2,12 @@ namespace SwooleTW\Http\Server; -use Psr\Container\ContainerInterface; - class PidManagerFactory { - public function __invoke(ContainerInterface $container) : PidManager + public function __invoke() : PidManager { - $config = $container->get('config'); - return new PidManager( - $config->get('swoole_http.server.options.pid_file') ?? sys_get_temp_dir() . '/swoole.pid' + config('swoole_http.server.options.pid_file') ?? sys_get_temp_dir() . '/swoole.pid' ); } } diff --git a/tests/Server/PidManagerFactoryTest.php b/tests/Server/PidManagerFactoryTest.php index 067010ad..a2f8e751 100644 --- a/tests/Server/PidManagerFactoryTest.php +++ b/tests/Server/PidManagerFactoryTest.php @@ -2,7 +2,6 @@ namespace SwooleTW\Http\Tests\Server; -use Psr\Container\ContainerInterface; use SwooleTW\Http\Server\PidManager; use SwooleTW\Http\Server\PidManagerFactory; use SwooleTW\Http\Tests\TestCase; @@ -13,8 +12,6 @@ public function testFactoryReturnsAPidManager() { $factory = new PidManagerFactory(); - $pidManager = $factory($this->prophesize(ContainerInterface::class)->reveal()); - - $this->assertInstanceOf(PidManager::class, $pidManager); + $this->assertInstanceOf(PidManager::class, $factory()); } } From 499e488868f9088b624bffb2dab18155b0c74803 Mon Sep 17 00:00:00 2001 From: Bill li Date: Mon, 27 May 2019 12:21:19 +0800 Subject: [PATCH 108/161] meh --- src/Server/PidManagerFactory.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Server/PidManagerFactory.php b/src/Server/PidManagerFactory.php index b116471e..c6513e85 100644 --- a/src/Server/PidManagerFactory.php +++ b/src/Server/PidManagerFactory.php @@ -2,12 +2,14 @@ namespace SwooleTW\Http\Server; +use Illuminate\Support\Facades\Config; + class PidManagerFactory { public function __invoke() : PidManager { return new PidManager( - config('swoole_http.server.options.pid_file') ?? sys_get_temp_dir() . '/swoole.pid' + Config::get('swoole_http.server.options.pid_file') ?? sys_get_temp_dir() . '/swoole.pid' ); } } From 0c80925bbb7cfb80d4995a980f506d5587daebc6 Mon Sep 17 00:00:00 2001 From: Bill li Date: Mon, 27 May 2019 12:45:06 +0800 Subject: [PATCH 109/161] fix. --- src/Server/PidManagerFactory.php | 7 ++++--- tests/Server/PidManagerFactoryTest.php | 11 ++++++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/Server/PidManagerFactory.php b/src/Server/PidManagerFactory.php index c6513e85..2b1cd5b9 100644 --- a/src/Server/PidManagerFactory.php +++ b/src/Server/PidManagerFactory.php @@ -2,14 +2,15 @@ namespace SwooleTW\Http\Server; -use Illuminate\Support\Facades\Config; +use Psr\Container\ContainerInterface; +use Illuminate\Contracts\Config\Repository as ConfigContract; class PidManagerFactory { - public function __invoke() : PidManager + public function __invoke(ContainerInterface $container): PidManager { return new PidManager( - Config::get('swoole_http.server.options.pid_file') ?? sys_get_temp_dir() . '/swoole.pid' + $container->get('config')->get('swoole_http.server.options.pid_file') ?? sys_get_temp_dir() . '/swoole.pid' ); } } diff --git a/tests/Server/PidManagerFactoryTest.php b/tests/Server/PidManagerFactoryTest.php index a2f8e751..f6df1c8e 100644 --- a/tests/Server/PidManagerFactoryTest.php +++ b/tests/Server/PidManagerFactoryTest.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http\Tests\Server; +use Illuminate\Container\Container; use SwooleTW\Http\Server\PidManager; use SwooleTW\Http\Server\PidManagerFactory; use SwooleTW\Http\Tests\TestCase; @@ -10,7 +11,15 @@ class PidManagerFactoryTest extends TestCase { public function testFactoryReturnsAPidManager() { - $factory = new PidManagerFactory(); + $factory = new PidManagerFactory($container = new Container); + + $config = m::mock(ConfigContract::class); + + $container->singleton(ConfigContract::class, function () use ($config) { + return $config; + }); + + $container->alias(ConfigContract::class, 'config'); $this->assertInstanceOf(PidManager::class, $factory()); } From 1bc5f1c9f2853a5a17d79d745fc01501a1435b75 Mon Sep 17 00:00:00 2001 From: Bill li Date: Mon, 27 May 2019 12:46:00 +0800 Subject: [PATCH 110/161] k --- tests/Server/PidManagerFactoryTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Server/PidManagerFactoryTest.php b/tests/Server/PidManagerFactoryTest.php index f6df1c8e..4f221f47 100644 --- a/tests/Server/PidManagerFactoryTest.php +++ b/tests/Server/PidManagerFactoryTest.php @@ -2,6 +2,7 @@ namespace SwooleTW\Http\Tests\Server; +use Mockery as m; use Illuminate\Container\Container; use SwooleTW\Http\Server\PidManager; use SwooleTW\Http\Server\PidManagerFactory; From 460c0a54837408e99564453ae88bc9e19724b120 Mon Sep 17 00:00:00 2001 From: Bill li Date: Mon, 27 May 2019 13:33:37 +0800 Subject: [PATCH 111/161] fix --- src/Server/Manager.php | 2 +- tests/Server/PidManagerFactoryTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 5fa3dad0..03f3a50f 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -148,7 +148,7 @@ public function onStart() $server = $this->container->make(Server::class); - $this->pidManager->write($server->master_pid, $server->manager_pid); + $this->pidManager->write($server->master_pid, $server->manager_pid ?? 0); $this->container->make('events')->dispatch('swoole.start', func_get_args()); } diff --git a/tests/Server/PidManagerFactoryTest.php b/tests/Server/PidManagerFactoryTest.php index 4f221f47..ff087b83 100644 --- a/tests/Server/PidManagerFactoryTest.php +++ b/tests/Server/PidManagerFactoryTest.php @@ -22,6 +22,6 @@ public function testFactoryReturnsAPidManager() $container->alias(ConfigContract::class, 'config'); - $this->assertInstanceOf(PidManager::class, $factory()); + $this->assertInstanceOf(PidManager::class, $factory($container)); } } From 85a5a4f49eb8b20f6dac8e1962a5a2816c6c7531 Mon Sep 17 00:00:00 2001 From: Bill li Date: Mon, 27 May 2019 14:17:05 +0800 Subject: [PATCH 112/161] k --- src/Server/PidManagerFactory.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Server/PidManagerFactory.php b/src/Server/PidManagerFactory.php index 2b1cd5b9..173b2194 100644 --- a/src/Server/PidManagerFactory.php +++ b/src/Server/PidManagerFactory.php @@ -9,8 +9,10 @@ class PidManagerFactory { public function __invoke(ContainerInterface $container): PidManager { + $config = $container->get('config'); + return new PidManager( - $container->get('config')->get('swoole_http.server.options.pid_file') ?? sys_get_temp_dir() . '/swoole.pid' + $config->get('swoole_http.server.options.pid_file') ?: sys_get_temp_dir() . '/swoole.pid' ); } } From 149ea79e3cf4167a05c7c6de03112bdccd9d1aee Mon Sep 17 00:00:00 2001 From: Bill li Date: Mon, 27 May 2019 14:17:35 +0800 Subject: [PATCH 113/161] add getConfig. --- tests/Server/PidManagerFactoryTest.php | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/tests/Server/PidManagerFactoryTest.php b/tests/Server/PidManagerFactoryTest.php index ff087b83..0daa7047 100644 --- a/tests/Server/PidManagerFactoryTest.php +++ b/tests/Server/PidManagerFactoryTest.php @@ -2,8 +2,8 @@ namespace SwooleTW\Http\Tests\Server; -use Mockery as m; use Illuminate\Container\Container; +use Mockery as m; use SwooleTW\Http\Server\PidManager; use SwooleTW\Http\Server\PidManagerFactory; use SwooleTW\Http\Tests\TestCase; @@ -14,7 +14,7 @@ public function testFactoryReturnsAPidManager() { $factory = new PidManagerFactory($container = new Container); - $config = m::mock(ConfigContract::class); + $config = $this->getConfig(); $container->singleton(ConfigContract::class, function () use ($config) { return $config; @@ -24,4 +24,21 @@ public function testFactoryReturnsAPidManager() $this->assertInstanceOf(PidManager::class, $factory($container)); } + + protected function getConfig() + { + $config = m::mock(ConfigContract::class); + $callback = function ($key) { + return $this->config[$key] ?? ''; + }; + + $config->shouldReceive('get') + ->with(m::type('string'), m::any()) + ->andReturnUsing($callback); + $config->shouldReceive('get') + ->with(m::type('string')) + ->andReturnUsing($callback); + + return $config; + } } From 21a3a073edbc5206260665e2b493c723a9dba04b Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 2 Jun 2019 15:10:25 +0800 Subject: [PATCH 114/161] fix task worker num for showing info --- src/Commands/HttpServerCommand.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Commands/HttpServerCommand.php b/src/Commands/HttpServerCommand.php index 26f85908..f4df59a6 100644 --- a/src/Commands/HttpServerCommand.php +++ b/src/Commands/HttpServerCommand.php @@ -217,7 +217,7 @@ protected function showInfos() $reactorNum = Arr::get($this->config, 'server.options.reactor_num'); $workerNum = Arr::get($this->config, 'server.options.worker_num'); $taskWorkerNum = Arr::get($this->config, 'server.options.task_worker_num'); - $isWebsocket = Arr::get($this->config, 'websocket.enabled'); + $hasTaskWorker = Arr::get($this->config, 'websocket.enabled') || Arr::get($this->config, 'queue.default') === 'swoole'; $logFile = Arr::get($this->config, 'server.options.log_file'); $table = [ @@ -229,7 +229,7 @@ protected function showInfos() ['Server Status', $isRunning ? 'Online' : 'Offline'], ['Reactor Num', $reactorNum], ['Worker Num', $workerNum], - ['Task Worker Num', $isWebsocket ? $taskWorkerNum : 0], + ['Task Worker Num', $hasTaskWorker ? $taskWorkerNum : 0], ['Websocket Mode', $isWebsocket ? 'On' : 'Off'], ['PID', $isRunning ? $pid : 'None'], ['Log Path', $logFile], From 5f1939a9e626f18e617464e261769592cd34c60b Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 2 Jun 2019 21:33:51 +0800 Subject: [PATCH 115/161] refactor pid manager and add missing tests --- src/Commands/HttpServerCommand.php | 30 ++---- src/HttpServiceProvider.php | 23 ++--- src/LaravelServiceProvider.php | 5 +- src/LumenServiceProvider.php | 5 +- src/Server/Manager.php | 16 +--- src/Server/PidManager.php | 125 ++++++++++++++----------- src/Server/PidManagerFactory.php | 18 ---- tests/Server/ManagerTest.php | 62 ++++++------ tests/Server/PidManagerFactoryTest.php | 44 --------- tests/Server/PidManagerTest.php | 97 +++++++++++++++++++ 10 files changed, 219 insertions(+), 206 deletions(-) delete mode 100644 src/Server/PidManagerFactory.php delete mode 100644 tests/Server/PidManagerFactoryTest.php create mode 100644 tests/Server/PidManagerTest.php diff --git a/src/Commands/HttpServerCommand.php b/src/Commands/HttpServerCommand.php index 6ef6e9d5..93b7ac1c 100644 --- a/src/Commands/HttpServerCommand.php +++ b/src/Commands/HttpServerCommand.php @@ -60,25 +60,6 @@ class HttpServerCommand extends Command */ protected $config; - /** - * A manager to handle pid about the application. - * - * @var PidManager - */ - protected $pidManager; - - /** - * Create a an new HttpServerCommand instance. - * - * @param PidManager $pidManager - */ - public function __construct(PidManager $pidManager) - { - parent::__construct(); - - $this->pidManager = $pidManager; - } - /** * Execute the console command. * @@ -170,7 +151,7 @@ protected function stop() // I don't known why Swoole didn't trigger "onShutdown" after sending SIGTERM. // So we should manually remove the pid file. - $this->pidManager->delete(); + $this->laravel->make(PidManager::class)->delete(); $this->info('> success'); } @@ -230,6 +211,7 @@ protected function showInfos() $taskWorkerNum = Arr::get($this->config, 'server.options.task_worker_num'); $hasTaskWorker = Arr::get($this->config, 'websocket.enabled') || Arr::get($this->config, 'queue.default') === 'swoole'; $logFile = Arr::get($this->config, 'server.options.log_file'); + $pidManager = $this->laravel->make(PidManager::class); $table = [ ['PHP Version', 'Version' => phpversion()], @@ -242,7 +224,7 @@ protected function showInfos() ['Worker Num', $workerNum], ['Task Worker Num', $hasTaskWorker ? $taskWorkerNum : 0], ['Websocket Mode', $isWebsocket ? 'On' : 'Off'], - ['PID', $isRunning ? implode(', ', $this->pidManager->read()) : 'None'], + ['PID', $isRunning ? implode(', ', $pidManager->read()) : 'None'], ['Log Path', $logFile], ]; @@ -294,9 +276,9 @@ protected function getHotReloadProcess($server) */ public function isRunning() { - $pids = $this->pidManager->read(); + $pids = $this->laravel->make(PidManager::class)->read(); - if ([] === $pids) { + if (! count($pids)) { return false; } @@ -322,7 +304,7 @@ public function isRunning() protected function killProcess($sig, $wait = 0) { Process::kill( - Arr::first($this->pidManager->read()), + Arr::first($this->laravel->make(PidManager::class)->read()), $sig ); diff --git a/src/HttpServiceProvider.php b/src/HttpServiceProvider.php index 5a4a698a..4bb77ddf 100644 --- a/src/HttpServiceProvider.php +++ b/src/HttpServiceProvider.php @@ -2,19 +2,18 @@ namespace SwooleTW\Http; -use Illuminate\Database\DatabaseManager; -use Illuminate\Queue\QueueManager; -use Illuminate\Support\ServiceProvider; -use SwooleTW\Http\Commands\HttpServerCommand; -use SwooleTW\Http\Coroutine\Connectors\ConnectorFactory; -use SwooleTW\Http\Coroutine\MySqlConnection; use SwooleTW\Http\Helpers\FW; -use SwooleTW\Http\Server\Facades\Server; +use Illuminate\Queue\QueueManager; use SwooleTW\Http\Server\PidManager; -use SwooleTW\Http\Server\PidManagerFactory; -use SwooleTW\Http\Task\Connectors\SwooleTaskConnector; use Swoole\Http\Server as HttpServer; +use Illuminate\Support\ServiceProvider; +use Illuminate\Database\DatabaseManager; +use SwooleTW\Http\Server\Facades\Server; +use SwooleTW\Http\Coroutine\MySqlConnection; +use SwooleTW\Http\Commands\HttpServerCommand; use Swoole\Websocket\Server as WebsocketServer; +use SwooleTW\Http\Task\Connectors\SwooleTaskConnector; +use SwooleTW\Http\Coroutine\Connectors\ConnectorFactory; /** * @codeCoverageIgnore @@ -45,12 +44,12 @@ abstract class HttpServiceProvider extends ServiceProvider */ public function register() { - $this->registerPidManager(); $this->mergeConfigs(); $this->setIsWebsocket(); $this->registerServer(); $this->registerManager(); $this->registerCommands(); + $this->registerPidManager(); $this->registerDatabaseDriver(); $this->registerSwooleQueueDriver(); } @@ -117,7 +116,9 @@ protected function mergeConfigs() protected function registerPidManager(): void { $this->app->singleton(PidManager::class, function() { - return call_user_func(new PidManagerFactory, $this->app); + return new PidManager( + $this->app->make('config')->get('swoole_http.server.options.pid_file'); + ); }); } diff --git a/src/LaravelServiceProvider.php b/src/LaravelServiceProvider.php index 5bab7cd9..3f58e2ca 100644 --- a/src/LaravelServiceProvider.php +++ b/src/LaravelServiceProvider.php @@ -2,10 +2,9 @@ namespace SwooleTW\Http; +use SwooleTW\Http\Server\Manager; use Illuminate\Contracts\Http\Kernel; use SwooleTW\Http\Middleware\AccessLog; -use SwooleTW\Http\Server\Manager; -use SwooleTW\Http\Server\PidManager; /** * @codeCoverageIgnore @@ -20,7 +19,7 @@ class LaravelServiceProvider extends HttpServiceProvider protected function registerManager() { $this->app->singleton(Manager::class, function ($app) { - return new Manager($app, 'laravel', base_path(), $this->app[PidManager::class]); + return new Manager($app, 'laravel'); }); $this->app->alias(Manager::class, 'swoole.manager'); diff --git a/src/LumenServiceProvider.php b/src/LumenServiceProvider.php index bed2e340..eab77c83 100644 --- a/src/LumenServiceProvider.php +++ b/src/LumenServiceProvider.php @@ -2,9 +2,8 @@ namespace SwooleTW\Http; -use SwooleTW\Http\Middleware\AccessLog; use SwooleTW\Http\Server\Manager; -use SwooleTW\Http\Server\PidManager; +use SwooleTW\Http\Middleware\AccessLog; /** * @codeCoverageIgnore @@ -19,7 +18,7 @@ class LumenServiceProvider extends HttpServiceProvider protected function registerManager() { $this->app->singleton(Manager::class, function ($app) { - return new Manager($app, 'lumen', base_path(), $this->app[PidManager::class]); + return new Manager($app, 'lumen'); }); $this->app->alias(Manager::class, 'swoole.manager'); diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 03f3a50f..d90a4347 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -9,6 +9,7 @@ use Illuminate\Support\Str; use SwooleTW\Http\Helpers\OS; use SwooleTW\Http\Server\Sandbox; +use SwooleTW\Http\Server\PidManager; use SwooleTW\Http\Task\SwooleTaskJob; use Illuminate\Support\Facades\Facade; use SwooleTW\Http\Websocket\Websocket; @@ -41,13 +42,6 @@ class Manager */ protected $container; - /** - * A manager to handle pid about the application. - * - * @var PidManager - */ - protected $pidManager; - /** * @var string */ @@ -89,12 +83,11 @@ class Manager * * @throws \Exception */ - public function __construct(Container $container, $framework, $basePath = null, PidManager $pidManager) + public function __construct(Container $container, $framework, $basePath = null) { $this->container = $container; $this->setFramework($framework); $this->setBasepath($basePath); - $this->pidManager = $pidManager; $this->initialize(); } @@ -147,8 +140,7 @@ public function onStart() $this->setProcessName('master process'); $server = $this->container->make(Server::class); - - $this->pidManager->write($server->master_pid, $server->manager_pid ?? 0); + $this->container->make(PidManager::class)->write($server->master_pid, $server->manager_pid ?? 0); $this->container->make('events')->dispatch('swoole.start', func_get_args()); } @@ -310,7 +302,7 @@ public function onFinish($server, $taskId, $data) */ public function onShutdown() { - $this->pidManager->delete(); + $this->container->make(PidManager::class)->delete(); } /** diff --git a/src/Server/PidManager.php b/src/Server/PidManager.php index ec21a4c5..d84016d0 100644 --- a/src/Server/PidManager.php +++ b/src/Server/PidManager.php @@ -4,69 +4,82 @@ class PidManager { - /** - * @var string - */ - private $pidFile = ''; + protected $pidFile; - public function __construct(string $pidFile) - { - $this->pidFile = $pidFile; - } + public function __construct(string $pidFile = null) + { + $this->setPidFile( + $pidFile ?: sys_get_temp_dir() . '/swoole.pid' + ); + } - /** - * Write master pid and manager pid to pid file - * - * @throws \RuntimeException When $pidFile is not writable - */ - public function write(int $masterPid, int $managerPid): void - { - if (! is_writable($this->pidFile) && ! is_writable(dirname($this->pidFile))) { - throw new \RuntimeException(sprintf('Pid file "%s" is not writable', $this->pidFile)); - } + /** + * Set pid file path + */ + public function setPidFile(string $pidFile): self + { + $this->pidFile = $pidFile; - file_put_contents($this->pidFile, $masterPid . ',' . $managerPid); - } + return $this; + } - /** - * Read master pid and manager pid from pid file - * - * @return string[] { - * @var string $masterPid - * @var string $managerPid - * } - */ - public function read(): array - { - $pids = []; + /** + * Write master pid and manager pid to pid file + * + * @throws \RuntimeException when $pidFile is not writable + */ + public function write(int $masterPid, int $managerPid): void + { + if (! is_writable($this->pidFile) + && ! is_writable(dirname($this->pidFile)) + ) { + throw new \RuntimeException( + sprintf('Pid file "%s" is not writable', $this->pidFile) + ); + } - if (is_readable($this->pidFile)) { - $content = file_get_contents($this->pidFile); - $pids = explode(',', $content); - } + file_put_contents($this->pidFile, $masterPid . ',' . $managerPid); + } - return $pids; - } + /** + * Read master pid and manager pid from pid file + * + * @return string[] { + * @var string $masterPid + * @var string $managerPid + * } + */ + public function read(): array + { + $pids = []; - /** - * Gets pid file path. - * - * @return string - */ - public function file() - { - return $this->pidFile; - } + if (is_readable($this->pidFile)) { + $content = file_get_contents($this->pidFile); + $pids = explode(',', $content); + } - /** - * Delete pid file - */ - public function delete(): bool - { - if (is_writable($this->pidFile)) { - return unlink($this->pidFile); - } + return $pids; + } - return false; - } + /** + * Gets pid file path. + * + * @return string + */ + public function file() + { + return $this->pidFile; + } + + /** + * Delete pid file + */ + public function delete(): bool + { + if (is_writable($this->pidFile)) { + return unlink($this->pidFile); + } + + return false; + } } diff --git a/src/Server/PidManagerFactory.php b/src/Server/PidManagerFactory.php deleted file mode 100644 index 173b2194..00000000 --- a/src/Server/PidManagerFactory.php +++ /dev/null @@ -1,18 +0,0 @@ -get('config'); - - return new PidManager( - $config->get('swoole_http.server.options.pid_file') ?: sys_get_temp_dir() . '/swoole.pid' - ); - } -} diff --git a/tests/Server/ManagerTest.php b/tests/Server/ManagerTest.php index 3875dbc1..7388c624 100644 --- a/tests/Server/ManagerTest.php +++ b/tests/Server/ManagerTest.php @@ -2,30 +2,30 @@ namespace SwooleTW\Http\Tests\Server; -use Illuminate\Container\Container; -use Illuminate\Contracts\Config\Repository as ConfigContract; -use Illuminate\Contracts\Debug\ExceptionHandler; -use Illuminate\Support\Facades\Config; -use Laravel\Lumen\Exceptions\Handler; use Mockery as m; -use SwooleTW\Http\Server\Facades\Server; +use Swoole\Table; +use Swoole\Http\Request; +use Swoole\Http\Response; use SwooleTW\Http\Server\Manager; -use SwooleTW\Http\Server\PidManagerFactory; use SwooleTW\Http\Server\Sandbox; -use SwooleTW\Http\Table\SwooleTable; use SwooleTW\Http\Tests\TestCase; +use Illuminate\Container\Container; +use SwooleTW\Http\Websocket\Parser; +use SwooleTW\Http\Server\PidManager; +use SwooleTW\Http\Table\SwooleTable; +use Laravel\Lumen\Exceptions\Handler; +use Illuminate\Support\Facades\Config; +use SwooleTW\Http\Websocket\Websocket; +use SwooleTW\Http\Server\Facades\Server; use SwooleTW\Http\Websocket\Facades\Pusher; -use SwooleTW\Http\Websocket\Facades\Websocket as WebsocketFacade; use SwooleTW\Http\Websocket\HandlerContract; -use SwooleTW\Http\Websocket\Parser; -use SwooleTW\Http\Websocket\Rooms\RoomContract; use SwooleTW\Http\Websocket\Rooms\TableRoom; +use SwooleTW\Http\Websocket\Rooms\RoomContract; +use Illuminate\Contracts\Debug\ExceptionHandler; use SwooleTW\Http\Websocket\SocketIO\SocketIOParser; use SwooleTW\Http\Websocket\SocketIO\WebsocketHandler; -use SwooleTW\Http\Websocket\Websocket; -use Swoole\Http\Request; -use Swoole\Http\Response; -use Swoole\Table; +use Illuminate\Contracts\Config\Repository as ConfigContract; +use SwooleTW\Http\Websocket\Facades\Websocket as WebsocketFacade; class ManagerTest extends TestCase { @@ -103,19 +103,18 @@ public function testStop() public function testOnStart() { - $filePutContents = false; - $this->mockMethod('file_put_contents', function () use (&$filePutContents) { - $filePutContents = true; - }); + $pidManager = m::mock(PidManager::class); + $pidManager->shouldReceive('write')->once(); $container = $this->getContainer(); $container->singleton('events', function () { return $this->getEvent('swoole.start'); }); + $container->singleton(PidManager::class, function () use ($pidManager) { + return $pidManager; + }); $manager = $this->getManager($container); $manager->onStart(); - - $this->assertTrue($filePutContents); } public function testOnManagerStart() @@ -308,21 +307,16 @@ public function testOnTask() public function testOnShutdown() { - $fileExists = false; - $this->mockMethod('file_exists', function () use (&$fileExists) { - return $fileExists = true; - }); + $pidManager = m::mock(PidManager::class); + $pidManager->shouldReceive('delete')->once(); - $unlink = false; - $this->mockMethod('unlink', function () use (&$unlink) { - return $unlink = true; + $container = $this->getContainer(); + $container->singleton(PidManager::class, function () use ($pidManager) { + return $pidManager; }); - $manager = $this->getManager(); + $manager = $this->getManager($container); $manager->onShutdown(); - - $this->assertTrue($fileExists); - $this->assertTrue($unlink); } public function testSetParser() @@ -578,9 +572,7 @@ public function testPushMessage() protected function getManager($container = null, $framework = 'laravel', $path = '/') { - $pidFacotry = (new PidManagerFactory)($this->getContainer()); - - return new Manager($container ?: $this->getContainer(), $framework, $path, $pidFacotry); + return new Manager($container ?: $this->getContainer(), $framework, $path); } protected function getWebsocketManager($container = null) diff --git a/tests/Server/PidManagerFactoryTest.php b/tests/Server/PidManagerFactoryTest.php deleted file mode 100644 index 0daa7047..00000000 --- a/tests/Server/PidManagerFactoryTest.php +++ /dev/null @@ -1,44 +0,0 @@ -getConfig(); - - $container->singleton(ConfigContract::class, function () use ($config) { - return $config; - }); - - $container->alias(ConfigContract::class, 'config'); - - $this->assertInstanceOf(PidManager::class, $factory($container)); - } - - protected function getConfig() - { - $config = m::mock(ConfigContract::class); - $callback = function ($key) { - return $this->config[$key] ?? ''; - }; - - $config->shouldReceive('get') - ->with(m::type('string'), m::any()) - ->andReturnUsing($callback); - $config->shouldReceive('get') - ->with(m::type('string')) - ->andReturnUsing($callback); - - return $config; - } -} diff --git a/tests/Server/PidManagerTest.php b/tests/Server/PidManagerTest.php new file mode 100644 index 00000000..1de8b109 --- /dev/null +++ b/tests/Server/PidManagerTest.php @@ -0,0 +1,97 @@ +assertEquals($pidFile, $pidManager->file()); + + $pidManager->setPidFile($pidFile = 'laravel-swoole'); + $this->assertEquals($pidFile, $pidManager->file()); + } + + public function testWrite() + { + $pidManager = new PidManager($pidFile = 'foo/bar'); + + $this->mockMethod('is_writable', function () { + return true; + }); + + $inputFilePath = ''; + $inputFileContent = ''; + $this->mockMethod('file_put_contents', function ($pidPath, $pidContent) use (&$inputFilePath, &$inputFileContent) { + $inputFilePath = $pidPath; + $inputFileContent = $pidContent; + }); + + $pidManager->write($masterPid = 1, $managerPid = 2); + + $this->assertEquals($pidFile, $inputFilePath); + $this->assertEquals('1,2', $inputFileContent); + } + + public function testWriteWithException() + { + $pidManager = new PidManager($pidFile = 'foo/bar'); + + $this->mockMethod('is_writable', function () { + return false; + }); + + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Pid file "foo/bar" is not writable'); + + $pidManager->write($masterPid = 1, $managerPid = 2); + } + + public function testRead() + { + $pidManager = new PidManager($pidFile = 'foo/bar'); + + $this->mockMethod('is_readable', function () { + return true; + }); + + $this->mockMethod('file_get_contents', function () { + return '1,2'; + }); + + $this->assertEquals( + ['1', '2'], + $pidManager->read() + ); + } + + public function testDelete() + { + $pidManager = new PidManager($pidFile = 'foo/bar'); + + $this->mockMethod('is_writable', function () { + return true; + }); + + $unlinkCalled = false; + $this->mockMethod('unlink', function () use (&$unlinkCalled) { + return $unlinkCalled = true; + }); + + $pidManager->delete(); + + $this->assertTrue($unlinkCalled); + } + + protected function mockMethod($name, \Closure $function, $namespace = null) + { + parent::mockMethod($name, $function, 'SwooleTW\Http\Server'); + } +} From 119726a3bf545e68198bc30306e0ac4d62ecb3f8 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 2 Jun 2019 21:38:15 +0800 Subject: [PATCH 116/161] fix syntax --- src/HttpServiceProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HttpServiceProvider.php b/src/HttpServiceProvider.php index 4bb77ddf..c4e2298a 100644 --- a/src/HttpServiceProvider.php +++ b/src/HttpServiceProvider.php @@ -117,7 +117,7 @@ protected function registerPidManager(): void { $this->app->singleton(PidManager::class, function() { return new PidManager( - $this->app->make('config')->get('swoole_http.server.options.pid_file'); + $this->app->make('config')->get('swoole_http.server.options.pid_file') ); }); } From 7368e9df6df76d10b5893b8f1d49e623bca8941a Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 2 Jun 2019 22:49:22 +0800 Subject: [PATCH 117/161] improve pid info --- src/Commands/HttpServerCommand.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Commands/HttpServerCommand.php b/src/Commands/HttpServerCommand.php index 93b7ac1c..0b1614b8 100644 --- a/src/Commands/HttpServerCommand.php +++ b/src/Commands/HttpServerCommand.php @@ -209,9 +209,11 @@ protected function showInfos() $reactorNum = Arr::get($this->config, 'server.options.reactor_num'); $workerNum = Arr::get($this->config, 'server.options.worker_num'); $taskWorkerNum = Arr::get($this->config, 'server.options.task_worker_num'); - $hasTaskWorker = Arr::get($this->config, 'websocket.enabled') || Arr::get($this->config, 'queue.default') === 'swoole'; + $isWebsocket = Arr::get($this->config, 'websocket.enabled'); + $hasTaskWorker = $isWebsocket || Arr::get($this->config, 'queue.default') === 'swoole'; $logFile = Arr::get($this->config, 'server.options.log_file'); $pidManager = $this->laravel->make(PidManager::class); + [$masterPid, $managerPid] = $pidManager->read(); $table = [ ['PHP Version', 'Version' => phpversion()], @@ -224,7 +226,8 @@ protected function showInfos() ['Worker Num', $workerNum], ['Task Worker Num', $hasTaskWorker ? $taskWorkerNum : 0], ['Websocket Mode', $isWebsocket ? 'On' : 'Off'], - ['PID', $isRunning ? implode(', ', $pidManager->read()) : 'None'], + ['Master PID', $isRunning ? $masterPid : 'None'], + ['Manager PID', $isRunning && $managerPid ? $managerPid : 'None'], ['Log Path', $logFile], ]; From d27e2c4ae14311f9e0737758f742d90587a023cb Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 2 Jun 2019 22:59:13 +0800 Subject: [PATCH 118/161] fix style --- src/Concerns/InteractsWithWebsocket.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Concerns/InteractsWithWebsocket.php b/src/Concerns/InteractsWithWebsocket.php index b51a450d..b55354a3 100644 --- a/src/Concerns/InteractsWithWebsocket.php +++ b/src/Concerns/InteractsWithWebsocket.php @@ -41,7 +41,7 @@ trait InteractsWithWebsocket protected $payloadParser; /** - * @var SwooleTW\Http\Websocket\Rooms\RoomContract + * @var \SwooleTW\Http\Websocket\Rooms\RoomContract */ protected $websocketRoom; @@ -310,7 +310,7 @@ protected function createRoom(string $class, array $settings): RoomContract */ protected function bindRoom(): void { - $this->app->singleton(RoomContract::class, function (Container $app) { + $this->app->singleton(RoomContract::class, function () { return $this->websocketRoom; }); From 073061192f5038253dc3bd1c09637ef766393e60 Mon Sep 17 00:00:00 2001 From: Karl Li Date: Tue, 11 Jun 2019 11:55:54 +0800 Subject: [PATCH 119/161] fix return value --- src/Websocket/Pusher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Websocket/Pusher.php b/src/Websocket/Pusher.php index 25be5854..32b8e91f 100644 --- a/src/Websocket/Pusher.php +++ b/src/Websocket/Pusher.php @@ -88,7 +88,7 @@ protected function __construct( * @param array $data * @param \Swoole\Websocket\Server $server * - * @return \SwooleTW\Http\Websocket\Push + * @return \SwooleTW\Http\Websocket\Pusher */ public static function make(array $data, $server) { From 3447ac6b102ef4206eb4ed74a748cc9f32743aa3 Mon Sep 17 00:00:00 2001 From: Karl Li Date: Tue, 11 Jun 2019 13:04:44 +0800 Subject: [PATCH 120/161] add swoole/ide-helper package for dev --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 69c534aa..704f9890 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,8 @@ "php-coveralls/php-coveralls": "^2.1", "mockery/mockery": "~1.0", "codedungeon/phpunit-result-printer": "^0.14.0", - "php-mock/php-mock": "^2.0" + "php-mock/php-mock": "^2.0", + "swoole/ide-helper": "@dev" }, "autoload": { "files": [ From 02c9f100a68dec7bdd813097a8c2b4c80e76cd03 Mon Sep 17 00:00:00 2001 From: Karl Li Date: Tue, 11 Jun 2019 13:05:49 +0800 Subject: [PATCH 121/161] add HandShakeHandler --- src/Websocket/HandShakeHandler.php | 48 ++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/Websocket/HandShakeHandler.php diff --git a/src/Websocket/HandShakeHandler.php b/src/Websocket/HandShakeHandler.php new file mode 100644 index 00000000..291fe17a --- /dev/null +++ b/src/Websocket/HandShakeHandler.php @@ -0,0 +1,48 @@ +header['sec-websocket-key']; + + if (0 === preg_match('#^[+/0-9A-Za-z]{21}[AQgw]==$#', $socketkey) || 16 !== strlen(base64_decode($socketkey))) { + $response->end(); + + return false; + } + + $headers = [ + 'Upgrade' => 'websocket', + 'Connection' => 'Upgrade', + 'Sec-WebSocket-Accept' => base64_encode(sha1($socketkey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true)), + 'Sec-WebSocket-Version' => '13', + ]; + + if (isset($request->header['sec-websocket-protocol'])) { + $headers['Sec-WebSocket-Protocol'] = $request->header['sec-websocket-protocol']; + } + + foreach ($headers as $header => $val) { + $response->header($header, $val); + } + + $response->status(101); + $response->end(); + + return true; + } +} From 2bb52971cb10ce12d7924f4bfcbfae114b67200d Mon Sep 17 00:00:00 2001 From: Karl Li Date: Tue, 11 Jun 2019 13:06:03 +0800 Subject: [PATCH 122/161] add test for HandShakeHandler --- tests/Websocket/HandShakeHandlerTest.php | 71 ++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 tests/Websocket/HandShakeHandlerTest.php diff --git a/tests/Websocket/HandShakeHandlerTest.php b/tests/Websocket/HandShakeHandlerTest.php new file mode 100644 index 00000000..abb5956c --- /dev/null +++ b/tests/Websocket/HandShakeHandlerTest.php @@ -0,0 +1,71 @@ +header['sec-websocket-key'] = 'Bet8DkPFq9ZxvIBvPcNy1A=='; + + $response = m::mock(Response::class); + $response->shouldReceive('header')->withAnyArgs()->times(4)->andReturnSelf(); + $response->shouldReceive('status')->with(101)->once()->andReturnSelf(); + $response->shouldReceive('end')->withAnyArgs()->once()->andReturnSelf(); + + $handler = new HandShakeHandler; + + // act + $actual = $handler->handle($request, $response); + + // assert + $this->assertTrue($actual); + } + + public function testHandleReturnFalse() + { + // arrange + $request = m::mock(Request::class); + $request->header['sec-websocket-key'] = 'test'; + + $response = m::mock(Response::class); + $response->shouldReceive('end')->withAnyArgs()->once()->andReturnSelf(); + + $handler = new HandShakeHandler; + + // act + $actual = $handler->handle($request, $response); + + // assert + $this->assertFalse($actual); + } + + public function testHandleWithSecWebsocketProtocol() + { + // arrange + $request = m::mock(Request::class); + $request->header['sec-websocket-key'] = 'Bet8DkPFq9ZxvIBvPcNy1A=='; + $request->header['sec-websocket-protocol'] = 'graphql-ws'; + + $response = m::mock(Response::class); + $response->shouldReceive('header')->withAnyArgs()->times(5)->andReturnSelf(); + $response->shouldReceive('status')->with(101)->once()->andReturnSelf(); + $response->shouldReceive('end')->withAnyArgs()->once()->andReturnSelf(); + + $handler = new HandShakeHandler; + + // act + $actual = $handler->handle($request, $response); + + // assert + $this->assertTrue($actual); + } +} From 7f5fb9e13ea21f9364a777a690b484061c17bfbd Mon Sep 17 00:00:00 2001 From: Karl Li Date: Tue, 11 Jun 2019 13:13:26 +0800 Subject: [PATCH 123/161] fix some warnings --- src/Concerns/InteractsWithWebsocket.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Concerns/InteractsWithWebsocket.php b/src/Concerns/InteractsWithWebsocket.php index b51a450d..22d7bf12 100644 --- a/src/Concerns/InteractsWithWebsocket.php +++ b/src/Concerns/InteractsWithWebsocket.php @@ -41,7 +41,7 @@ trait InteractsWithWebsocket protected $payloadParser; /** - * @var SwooleTW\Http\Websocket\Rooms\RoomContract + * @var \SwooleTW\Http\Websocket\Rooms\RoomContract */ protected $websocketRoom; @@ -160,6 +160,8 @@ public function onClose($server, $fd, $reactorId) * Indicates if a packet is websocket push action. * * @param mixed + * + * @return bool */ protected function isWebsocketPushPacket($packet) { @@ -167,7 +169,7 @@ protected function isWebsocketPushPacket($packet) return false; } - return $this->isWebsocket + return $this->isServerWebsocket && array_key_exists('action', $packet) && $packet['action'] === Websocket::PUSH_ACTION; } From cfd9f903a66fe4e4b975b733338bb3ea95803908 Mon Sep 17 00:00:00 2001 From: Karl Li Date: Tue, 11 Jun 2019 14:59:35 +0800 Subject: [PATCH 124/161] add config for handshake --- config/swoole_websocket.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/config/swoole_websocket.php b/config/swoole_websocket.php index d01a1edb..6e88949e 100644 --- a/config/swoole_websocket.php +++ b/config/swoole_websocket.php @@ -35,6 +35,17 @@ // SwooleTW\Http\Websocket\Middleware\Authenticate::class, ], + /* + |-------------------------------------------------------------------------- + | Websocket handler for onHandShake callback + | If enable, onOpen would not be triggered + |-------------------------------------------------------------------------- + */ + 'handshake' => [ + 'enabled' => false, + 'handler' => SwooleTW\Http\Websocket\HandShakeHandler::class, + ], + /* |-------------------------------------------------------------------------- | Default websocket driver From 8b71ff08df5abe22f4391f0f785aab0983ecf6c6 Mon Sep 17 00:00:00 2001 From: Karl Li Date: Tue, 11 Jun 2019 14:59:56 +0800 Subject: [PATCH 125/161] add onHandShake to InteractsWithWebsocket --- src/Concerns/InteractsWithWebsocket.php | 44 ++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/Concerns/InteractsWithWebsocket.php b/src/Concerns/InteractsWithWebsocket.php index 22d7bf12..e5039087 100644 --- a/src/Concerns/InteractsWithWebsocket.php +++ b/src/Concerns/InteractsWithWebsocket.php @@ -88,6 +88,46 @@ public function onOpen($server, $swooleRequest) } } + /** + * @param \Swoole\Http\Request $swooleRequest + * @param \Swoole\Http\Response $response + * + * @return bool + * @throws \Illuminate\Contracts\Container\BindingResolutionException + */ + public function onHandShake($swooleRequest, $response) + { + $illuminateRequest = Request::make($swooleRequest)->toIlluminate(); + $websocket = $this->app->make(Websocket::class); + $sandbox = $this->app->make(Sandbox::class); + $handler = $this->container->make('config')->get('swoole_websocket.handshake.handler'); + + try { + $websocket->reset(true)->setSender($swooleRequest->fd); + // set currnt request to sandbox + $sandbox->setRequest($illuminateRequest); + // enable sandbox + $sandbox->enable(); + + if (! $this->app->make($handler)->handle($swooleRequest, $response)) { + return false; + } + // trigger 'connect' websocket event + if ($websocket->eventExists('connect')) { + // set sandbox container to websocket pipeline + $websocket->setContainer($sandbox->getApplication()); + $websocket->call('connect', $illuminateRequest); + } + + return true; + } catch (Throwable $e) { + $this->logServerError($e); + } finally { + // disable and recycle sandbox resource + $sandbox->disable(); + } + } + /** * "onMessage" listener. * @@ -222,7 +262,9 @@ protected function prepareWebsocket() $parser = $config->get('swoole_websocket.parser'); if ($isWebsocket) { - $this->events = array_merge($this->events ?? [], $this->wsEvents); + $handshake = $config->get('swoole_websocket.handshake.enabled'); + + $this->events = array_merge($this->events ?? [], array_merge($this->wsEvents, $handshake ? ['handshake'] : [])); $this->isServerWebsocket = true; $this->prepareWebsocketRoom(); $this->setPayloadParser(new $parser); From 7b0ca35092bd7490a72581ca346b0c9434683107 Mon Sep 17 00:00:00 2001 From: Karl Li Date: Tue, 11 Jun 2019 15:00:05 +0800 Subject: [PATCH 126/161] add onHandShake test --- tests/Server/ManagerTest.php | 64 +++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/tests/Server/ManagerTest.php b/tests/Server/ManagerTest.php index 7388c624..d0dcd931 100644 --- a/tests/Server/ManagerTest.php +++ b/tests/Server/ManagerTest.php @@ -10,6 +10,7 @@ use SwooleTW\Http\Server\Sandbox; use SwooleTW\Http\Tests\TestCase; use Illuminate\Container\Container; +use SwooleTW\Http\Websocket\HandShakeHandler; use SwooleTW\Http\Websocket\Parser; use SwooleTW\Http\Server\PidManager; use SwooleTW\Http\Table\SwooleTable; @@ -17,7 +18,6 @@ use Illuminate\Support\Facades\Config; use SwooleTW\Http\Websocket\Websocket; use SwooleTW\Http\Server\Facades\Server; -use SwooleTW\Http\Websocket\Facades\Pusher; use SwooleTW\Http\Websocket\HandlerContract; use SwooleTW\Http\Websocket\Rooms\TableRoom; use SwooleTW\Http\Websocket\Rooms\RoomContract; @@ -48,6 +48,8 @@ class ManagerTest extends TestCase 'swoole_http.websocket.enabled' => true, 'swoole_websocket.parser' => SocketIOParser::class, 'swoole_websocket.handler' => WebsocketHandler::class, + 'swoole_websocket.handshake.enabled' => true, + 'swoole_websocket.handshake.handler' => HandShakeHandler::class, 'swoole_websocket.default' => 'table', 'swoole_websocket.settings.table' => [ 'room_rows' => 10, @@ -414,6 +416,66 @@ public function testOnOpen() $manager->onOpen(m::mock('server'), $request); } + public function testOnHandShake() + { + $request = m::mock(Request::class); + $request->shouldReceive('rawcontent') + ->once() + ->andReturn([]); + $request->fd = 1; + $request->header['sec-websocket-key'] = 'Bet8DkPFq9ZxvIBvPcNy1A=='; + + $response = m::mock(Response::class); + $response->shouldReceive('header')->withAnyArgs()->times(4)->andReturnSelf(); + $response->shouldReceive('status')->with(101)->once()->andReturnSelf(); + $response->shouldReceive('end')->withAnyArgs()->once()->andReturnSelf(); + + $container = $this->getContainer($this->getServer(), $this->getConfig(true)); + $container->singleton(Websocket::class, function () { + $websocket = m::mock(Websocket::class); + $websocket->shouldReceive('reset') + ->with(true) + ->once() + ->andReturnSelf(); + $websocket->shouldReceive('setSender') + ->with(1) + ->once(); + $websocket->shouldReceive('eventExists') + ->with('connect') + ->once() + ->andReturn(true); + $websocket->shouldReceive('setContainer') + ->with(m::type(Container::class)) + ->once(); + $websocket->shouldReceive('call') + ->with('connect', m::type('Illuminate\Http\Request')) + ->once(); + + return $websocket; + }); + $container->singleton(Sandbox::class, function () { + $sandbox = m::mock(Sandbox::class); + $sandbox->shouldReceive('setRequest') + ->with(m::type('Illuminate\Http\Request')) + ->once(); + $sandbox->shouldReceive('enable') + ->once(); + $sandbox->shouldReceive('disable') + ->once(); + $sandbox->shouldReceive('getApplication') + ->once() + ->andReturn(m::mock(Container::class)); + + return $sandbox; + }); + + $container->alias(Sandbox::class, 'swoole.sandbox'); + + $manager = $this->getWebsocketManager(); + $manager->setApplication($container); + $manager->onHandShake($request, $response); + } + public function testOnMessage() { $frame = m::mock('frame'); From b7f4d363d84b0608897bb8aa7f71e10b290e1be2 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 16 Jun 2019 16:30:09 +0800 Subject: [PATCH 127/161] fix potential package configuration mismatched in lumen --- src/HttpServiceProvider.php | 47 ++++++++++++++++++++++++------------ src/LumenServiceProvider.php | 9 +++++++ 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/HttpServiceProvider.php b/src/HttpServiceProvider.php index c4e2298a..fdc7460a 100644 --- a/src/HttpServiceProvider.php +++ b/src/HttpServiceProvider.php @@ -38,14 +38,35 @@ abstract class HttpServiceProvider extends ServiceProvider protected static $server; /** - * Register the service provider. + * Boot the service provider. * * @return void */ - public function register() + public function boot() { + $this->publishFiles(); + $this->loadConfigs(); $this->mergeConfigs(); $this->setIsWebsocket(); + + $config = $this->app->make('config'); + + if ($config->get('swoole_http.websocket.enabled')) { + $this->bootWebsocketRoutes(); + } + + if ($config->get('swoole_http.server.access_log')) { + $this->pushAccessLogMiddleware(); + } + } + + /** + * Register the service provider. + * + * @return void + */ + public function register() + { $this->registerServer(); $this->registerManager(); $this->registerCommands(); @@ -76,27 +97,23 @@ abstract protected function bootWebsocketRoutes(); abstract protected function pushAccessLogMiddleware(); /** - * Boot the service provider. - * - * @return void + * Publish files of this package. */ - public function boot() + protected function publishFiles() { $this->publishes([ __DIR__ . '/../config/swoole_http.php' => base_path('config/swoole_http.php'), __DIR__ . '/../config/swoole_websocket.php' => base_path('config/swoole_websocket.php'), __DIR__ . '/../routes/websocket.php' => base_path('routes/websocket.php'), ], 'laravel-swoole'); + } - $config = $this->app->make('config'); - - if ($config->get('swoole_http.websocket.enabled')) { - $this->bootWebsocketRoutes(); - } - - if ($config->get('swoole_http.server.access_log')) { - $this->pushAccessLogMiddleware(); - } + /** + * Load configurations. + */ + protected function loadConfigs() + { + // do nothing } /** diff --git a/src/LumenServiceProvider.php b/src/LumenServiceProvider.php index eab77c83..3270ded9 100644 --- a/src/LumenServiceProvider.php +++ b/src/LumenServiceProvider.php @@ -10,6 +10,15 @@ */ class LumenServiceProvider extends HttpServiceProvider { + /** + * Load configurations. + */ + protected function loadConfigs() + { + $this->app->configure('swoole_http'); + $this->app->configure('swoole_websocket'); + } + /** * Register manager. * From f83b952c2618cba9c4104a853ea4c6869901bf77 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 16 Jun 2019 16:36:23 +0800 Subject: [PATCH 128/161] fix isServerWebsocket function in InteractsWithWebsocket --- src/Concerns/InteractsWithWebsocket.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Concerns/InteractsWithWebsocket.php b/src/Concerns/InteractsWithWebsocket.php index b55354a3..687bf0db 100644 --- a/src/Concerns/InteractsWithWebsocket.php +++ b/src/Concerns/InteractsWithWebsocket.php @@ -236,8 +236,11 @@ protected function prepareWebsocket() */ protected function isServerWebsocket(int $fd): bool { - return (bool) $this->container->make(Server::class) - ->connection_info($fd)['websocket_status'] ?? false; + return array_key_exists( + 'websocket_status', + $this->container->make(Server::class) + ->connection_info($fd) + ); } /** From 924363ba183d4605005175b337b2cfda78c138ab Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 16 Jun 2019 18:17:04 +0800 Subject: [PATCH 129/161] improve onHandShake callback --- config/swoole_websocket.php | 3 +- src/Concerns/InteractsWithWebsocket.php | 79 ++++++++++--------------- tests/Server/ManagerTest.php | 6 ++ 3 files changed, 38 insertions(+), 50 deletions(-) diff --git a/config/swoole_websocket.php b/config/swoole_websocket.php index 6e88949e..867b9df8 100644 --- a/config/swoole_websocket.php +++ b/config/swoole_websocket.php @@ -37,8 +37,7 @@ /* |-------------------------------------------------------------------------- - | Websocket handler for onHandShake callback - | If enable, onOpen would not be triggered + | Websocket handler for customized onHandShake callback |-------------------------------------------------------------------------- */ 'handshake' => [ diff --git a/src/Concerns/InteractsWithWebsocket.php b/src/Concerns/InteractsWithWebsocket.php index 307068e4..6872529e 100644 --- a/src/Concerns/InteractsWithWebsocket.php +++ b/src/Concerns/InteractsWithWebsocket.php @@ -53,54 +53,33 @@ trait InteractsWithWebsocket protected $wsEvents = ['open', 'message', 'close']; /** - * "onOpen" listener. - * - * @param \Swoole\Websocket\Server $server + * "onHandShake" listener. * @param \Swoole\Http\Request $swooleRequest + * @param \Swoole\Http\Response $response */ - public function onOpen($server, $swooleRequest) + public function onHandShake($swooleRequest, $response) { - $illuminateRequest = Request::make($swooleRequest)->toIlluminate(); - $websocket = $this->app->make(Websocket::class); - $sandbox = $this->app->make(Sandbox::class); - - try { - $websocket->reset(true)->setSender($swooleRequest->fd); - // set currnt request to sandbox - $sandbox->setRequest($illuminateRequest); - // enable sandbox - $sandbox->enable(); - // check if socket.io connection established - if (! $this->websocketHandler->onOpen($swooleRequest->fd, $illuminateRequest)) { - return; - } - // trigger 'connect' websocket event - if ($websocket->eventExists('connect')) { - // set sandbox container to websocket pipeline - $websocket->setContainer($sandbox->getApplication()); - $websocket->call('connect', $illuminateRequest); - } - } catch (Throwable $e) { - $this->logServerError($e); - } finally { - // disable and recycle sandbox resource - $sandbox->disable(); - } + $this->onOpen( + $this->app->make(Server::class), + $swooleRequest, + $response + ); } /** - * @param \Swoole\Http\Request $swooleRequest - * @param \Swoole\Http\Response $response + * "onOpen" listener. * - * @return bool - * @throws \Illuminate\Contracts\Container\BindingResolutionException + * @param \Swoole\Websocket\Server $server + * @param \Swoole\Http\Request $swooleRequest + * @param \Swoole\Http\Response $response (optional) */ - public function onHandShake($swooleRequest, $response) + public function onOpen($server, $swooleRequest, $response = null) { $illuminateRequest = Request::make($swooleRequest)->toIlluminate(); $websocket = $this->app->make(Websocket::class); $sandbox = $this->app->make(Sandbox::class); - $handler = $this->container->make('config')->get('swoole_websocket.handshake.handler'); + $handshakeHandler = $this->app->make('config') + ->get('swoole_websocket.handshake.handler'); try { $websocket->reset(true)->setSender($swooleRequest->fd); @@ -108,9 +87,13 @@ public function onHandShake($swooleRequest, $response) $sandbox->setRequest($illuminateRequest); // enable sandbox $sandbox->enable(); - - if (! $this->app->make($handler)->handle($swooleRequest, $response)) { - return false; + // call customized handshake handler + if ($response && ! $this->app->make($handshakeHandler)->handle($swooleRequest, $response)) { + return; + } + // check if socket.io connection established + if (! $this->websocketHandler->onOpen($swooleRequest->fd, $illuminateRequest)) { + return; } // trigger 'connect' websocket event if ($websocket->eventExists('connect')) { @@ -118,8 +101,6 @@ public function onHandShake($swooleRequest, $response) $websocket->setContainer($sandbox->getApplication()); $websocket->call('connect', $illuminateRequest); } - - return true; } catch (Throwable $e) { $this->logServerError($e); } finally { @@ -258,17 +239,19 @@ public function getPayloadParser() protected function prepareWebsocket() { $config = $this->container->make('config'); - $isWebsocket = $config->get('swoole_http.websocket.enabled'); $parser = $config->get('swoole_websocket.parser'); - if ($isWebsocket) { - $handshake = $config->get('swoole_websocket.handshake.enabled'); + if (! $this->isServerWebsocket = $config->get('swoole_http.websocket.enabled')) { + return; + } - $this->events = array_merge($this->events ?? [], array_merge($this->wsEvents, $handshake ? ['handshake'] : [])); - $this->isServerWebsocket = true; - $this->prepareWebsocketRoom(); - $this->setPayloadParser(new $parser); + if ($config->get('swoole_websocket.handshake.enabled')) { + $this->wsEvents = array_merge($this->wsEvents, ['handshake']); } + + $this->events = array_merge($this->events ?? [], $this->wsEvents); + $this->prepareWebsocketRoom(); + $this->setPayloadParser(new $parser); } /** diff --git a/tests/Server/ManagerTest.php b/tests/Server/ManagerTest.php index d0dcd931..31f8db91 100644 --- a/tests/Server/ManagerTest.php +++ b/tests/Server/ManagerTest.php @@ -471,8 +471,14 @@ public function testOnHandShake() $container->alias(Sandbox::class, 'swoole.sandbox'); + $handler = m::mock(HandlerContract::class); + $handler->shouldReceive('onOpen') + ->with(1, m::type('Illuminate\Http\Request')) + ->andReturn(true); + $manager = $this->getWebsocketManager(); $manager->setApplication($container); + $manager->setWebsocketHandler($handler); $manager->onHandShake($request, $response); } From 5e2706999788814ac0dfcdbd34e8e93bad0d71e2 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Thu, 4 Jul 2019 22:46:47 +0800 Subject: [PATCH 130/161] make pid file compatible with older versions --- src/Commands/HttpServerCommand.php | 5 +++-- src/Server/PidManager.php | 5 ++++- tests/Server/PidManagerTest.php | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Commands/HttpServerCommand.php b/src/Commands/HttpServerCommand.php index 0b1614b8..afe3bff1 100644 --- a/src/Commands/HttpServerCommand.php +++ b/src/Commands/HttpServerCommand.php @@ -212,8 +212,9 @@ protected function showInfos() $isWebsocket = Arr::get($this->config, 'websocket.enabled'); $hasTaskWorker = $isWebsocket || Arr::get($this->config, 'queue.default') === 'swoole'; $logFile = Arr::get($this->config, 'server.options.log_file'); - $pidManager = $this->laravel->make(PidManager::class); - [$masterPid, $managerPid] = $pidManager->read(); + $pids = $this->laravel->make(PidManager::class)->read(); + $masterPid = $pids['masterPid'] ?? null; + $managerPid = $pids['managerPid'] ?? null; $table = [ ['PHP Version', 'Version' => phpversion()], diff --git a/src/Server/PidManager.php b/src/Server/PidManager.php index d84016d0..1e17babd 100644 --- a/src/Server/PidManager.php +++ b/src/Server/PidManager.php @@ -58,7 +58,10 @@ public function read(): array $pids = explode(',', $content); } - return $pids; + return [ + 'masterPid' => $pids[0] ?? null, + 'managerPid' => $pids[1] ?? null + ]; } /** diff --git a/tests/Server/PidManagerTest.php b/tests/Server/PidManagerTest.php index 1de8b109..2977055c 100644 --- a/tests/Server/PidManagerTest.php +++ b/tests/Server/PidManagerTest.php @@ -67,7 +67,7 @@ public function testRead() }); $this->assertEquals( - ['1', '2'], + ['masterPid' => '1', 'managerPid' => '2'], $pidManager->read() ); } From 277399fa7e1b4598f5f1a68a4f535ff98cf2d0c2 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Fri, 5 Jul 2019 11:19:15 +0800 Subject: [PATCH 131/161] fix pids in isRunning --- src/Commands/HttpServerCommand.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Commands/HttpServerCommand.php b/src/Commands/HttpServerCommand.php index afe3bff1..5ed1d959 100644 --- a/src/Commands/HttpServerCommand.php +++ b/src/Commands/HttpServerCommand.php @@ -286,7 +286,8 @@ public function isRunning() return false; } - [$masterPid, $managerPid] = $pids; + $masterPid = $pids['masterPid'] ?? null; + $managerPid = $pids['managerPid'] ?? null; if ($managerPid) { // Swoole process mode From 6c7332689932e08c1b681e736c9e96c675a3bc96 Mon Sep 17 00:00:00 2001 From: Vladyslav Korniienko Date: Fri, 26 Jul 2019 20:13:08 +0300 Subject: [PATCH 132/161] Update Websocket.php --- src/Websocket/Facades/Websocket.php | 32 ++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Websocket/Facades/Websocket.php b/src/Websocket/Facades/Websocket.php index 9f054036..6fedbcb4 100644 --- a/src/Websocket/Facades/Websocket.php +++ b/src/Websocket/Facades/Websocket.php @@ -5,30 +5,30 @@ use Illuminate\Support\Facades\Facade; /** - * @method static this broadcast() - * @method static this to($values) - * @method static this join($rooms) - * @method static this leave($rooms) + * @method static $this broadcast() + * @method static $this to($values) + * @method static $this join($rooms) + * @method static $this leave($rooms) * @method static boolean emit($event, $data) - * @method static this in($room) - * @method static this on($event, $callback) + * @method static $this in($room) + * @method static $this on($event, $callback) * @method static boolean eventExists($event) * @method static mixed call($event, $data) * @method static boolean close($fd) - * @method static this setSender($fd) + * @method static $this setSender($fd) * @method static int getSender() * @method static boolean getIsBroadcast() * @method static array getTo() - * @method static this reset() - * @method static this middleware($middleware) - * @method static this setContainer($container) - * @method static this setPipeline($pipeline) + * @method static $this reset() + * @method static $this middleware($middleware) + * @method static $this setContainer($container) + * @method static $this setPipeline($pipeline) * @method static \Illuminate\Contracts\Pipeline\Pipeline getPipeline() * @method static mixed loginUsing($user) - * @method static this loginUsingId($userId) - * @method static this logout() - * @method static this toUser($users) - * @method static this toUserId($userIds) + * @method static $this loginUsingId($userId) + * @method static $this logout() + * @method static $this toUser($users) + * @method static $this toUserId($userIds) * @method static string getUserId() * @method static boolean isUserIdOnline($userId) * @@ -45,4 +45,4 @@ protected static function getFacadeAccessor() { return 'swoole.websocket'; } -} \ No newline at end of file +} From 719053dca7ba85fd7e69457c34231afde948c358 Mon Sep 17 00:00:00 2001 From: Vladyslav Korniienko Date: Fri, 26 Jul 2019 20:13:24 +0300 Subject: [PATCH 133/161] Update Room.php --- src/Websocket/Facades/Room.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Websocket/Facades/Room.php b/src/Websocket/Facades/Room.php index 5b1919c2..5050e4f6 100644 --- a/src/Websocket/Facades/Room.php +++ b/src/Websocket/Facades/Room.php @@ -5,9 +5,9 @@ use Illuminate\Support\Facades\Facade; /** - * @method static this prepare() - * @method static this add($fd, $rooms) - * @method static this delete($fd, $rooms) + * @method static $this prepare() + * @method static $this add($fd, $rooms) + * @method static $this delete($fd, $rooms) * @method static array getClients($room) * @method static array getRooms($fd) * @@ -24,4 +24,4 @@ protected static function getFacadeAccessor() { return 'swoole.room'; } -} \ No newline at end of file +} From 0351741bcf276f6f64bb20bd13e96692cff62797 Mon Sep 17 00:00:00 2001 From: Yuriy Potemkin Date: Sat, 10 Aug 2019 13:35:36 +0300 Subject: [PATCH 134/161] fixes for working with websocket in jobs --- src/Server/Manager.php | 10 ++++++---- src/Websocket/Websocket.php | 37 +++++++++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/Server/Manager.php b/src/Server/Manager.php index d90a4347..f25b1143 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -122,13 +122,18 @@ protected function initialize() */ protected function setSwooleServerListeners() { + $server = $this->container->make(Server::class); + if ($server->taskworker){ + return; + } + foreach ($this->events as $event) { $listener = Str::camel("on_$event"); $callback = method_exists($this, $listener) ? [$this, $listener] : function () use ($event) { $this->container->make('events')->dispatch("swoole.$event", func_get_args()); }; - $this->container->make(Server::class)->on($event, $callback); + $server->on($event, $callback); } } @@ -170,11 +175,8 @@ public function onWorkerStart($server) $this->container->make('events')->dispatch('swoole.workerStart', func_get_args()); - // don't init laravel app in task workers if ($server->taskworker) { $this->setProcessName('task process'); - - return; } $this->setProcessName('worker process'); diff --git a/src/Websocket/Websocket.php b/src/Websocket/Websocket.php index 18fe56bd..981dd0ba 100644 --- a/src/Websocket/Websocket.php +++ b/src/Websocket/Websocket.php @@ -8,6 +8,7 @@ use Illuminate\Support\Facades\Config; use InvalidArgumentException; use SwooleTW\Http\Server\Facades\Server; +use SwooleTW\Http\Server\Manager; use SwooleTW\Http\Websocket\Rooms\RoomContract; /** @@ -172,17 +173,33 @@ public function emit(string $event, $data): bool return false; } - $result = App::make(Server::class)->task([ - 'action' => static::PUSH_ACTION, - 'data' => [ - 'sender' => $this->sender, - 'fds' => $fds, + /** @var Server $server */ + $server = App::make(Server::class); + + if ($server->taskworker) { + /** @var Manager $manager */ + $manager = App::make(Manager::class); + $result = $manager->pushMessage($server, [ + 'sender' => $this->sender, + 'fds' => $fds, 'broadcast' => $this->isBroadcast, - 'assigned' => $assigned, - 'event' => $event, - 'message' => $data, - ], - ]); + 'assigned' => $assigned, + 'event' => $event, + 'message' => $data, + ]); + } else { + $result = $server->task([ + 'action' => static::PUSH_ACTION, + 'data' => [ + 'sender' => $this->sender, + 'fds' => $fds, + 'broadcast' => $this->isBroadcast, + 'assigned' => $assigned, + 'event' => $event, + 'message' => $data, + ], + ]); + } $this->reset(); From 18b2023ff99e61755e628a5102d6c087de609705 Mon Sep 17 00:00:00 2001 From: Yuriy Potemkin Date: Sun, 11 Aug 2019 18:24:46 +0300 Subject: [PATCH 135/161] test fixes --- src/Websocket/Websocket.php | 6 ++++-- tests/Server/ManagerTest.php | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Websocket/Websocket.php b/src/Websocket/Websocket.php index 981dd0ba..9f83a4bb 100644 --- a/src/Websocket/Websocket.php +++ b/src/Websocket/Websocket.php @@ -176,10 +176,10 @@ public function emit(string $event, $data): bool /** @var Server $server */ $server = App::make(Server::class); - if ($server->taskworker) { + if (!empty($server->taskworker)) { /** @var Manager $manager */ $manager = App::make(Manager::class); - $result = $manager->pushMessage($server, [ + $manager->pushMessage($server, [ 'sender' => $this->sender, 'fds' => $fds, 'broadcast' => $this->isBroadcast, @@ -187,6 +187,8 @@ public function emit(string $event, $data): bool 'event' => $event, 'message' => $data, ]); + + $result = true; } else { $result = $server->task([ 'action' => static::PUSH_ACTION, diff --git a/tests/Server/ManagerTest.php b/tests/Server/ManagerTest.php index 31f8db91..2f56f526 100644 --- a/tests/Server/ManagerTest.php +++ b/tests/Server/ManagerTest.php @@ -178,7 +178,8 @@ public function testOnTaskWorkerStart() return $this->getEvent('swoole.workerStart'); }); - $manager = $this->getManager($container); + $path = __DIR__ . '/../fixtures'; + $manager = $this->getManager($container, $framework = 'laravel', $path); $this->assertNull($manager->onWorkerStart($server)); } From 61cb4d1724bd01c5b6a197a48ef11dbedf9ee515 Mon Sep 17 00:00:00 2001 From: netdown Date: Tue, 13 Aug 2019 15:25:15 +0200 Subject: [PATCH 136/161] Set request for auth handler --- src/Websocket/Middleware/Authenticate.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Websocket/Middleware/Authenticate.php b/src/Websocket/Middleware/Authenticate.php index ccc4bfa9..caf1c675 100644 --- a/src/Websocket/Middleware/Authenticate.php +++ b/src/Websocket/Middleware/Authenticate.php @@ -42,6 +42,7 @@ public function __construct(Auth $auth) public function handle($request, Closure $next) { try { + $this->auth->setRequest($request); if ($user = $this->auth->authenticate()) { $request->setUserResolver(function () use ($user) { return $user; From d7e47aa4be7bb60fc9b3fccb8c19491291481aa6 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 25 Aug 2019 20:46:46 +0800 Subject: [PATCH 137/161] add missing test for emitInTaskWorker --- src/Server/Manager.php | 14 +++---- src/Websocket/Websocket.php | 36 ++++++---------- tests/Websocket/WebsocketTest.php | 68 +++++++++++++++++++++++++++---- 3 files changed, 78 insertions(+), 40 deletions(-) diff --git a/src/Server/Manager.php b/src/Server/Manager.php index f25b1143..0f751cf6 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -114,7 +114,10 @@ protected function initialize() { $this->createTables(); $this->prepareWebsocket(); - $this->setSwooleServerListeners(); + + if (! $this->container->make(Server::class)->taskworker) { + $this->setSwooleServerListeners(); + } } /** @@ -123,10 +126,6 @@ protected function initialize() protected function setSwooleServerListeners() { $server = $this->container->make(Server::class); - if ($server->taskworker){ - return; - } - foreach ($this->events as $event) { $listener = Str::camel("on_$event"); $callback = method_exists($this, $listener) ? [$this, $listener] : function () use ($event) { @@ -175,10 +174,7 @@ public function onWorkerStart($server) $this->container->make('events')->dispatch('swoole.workerStart', func_get_args()); - if ($server->taskworker) { - $this->setProcessName('task process'); - } - $this->setProcessName('worker process'); + $this->setProcessName($server->taskworker ? 'task process' : 'worker process'); // clear events instance in case of repeated listeners in worker process Facade::clearResolvedInstance('events'); diff --git a/src/Websocket/Websocket.php b/src/Websocket/Websocket.php index 9f83a4bb..aa9c45bb 100644 --- a/src/Websocket/Websocket.php +++ b/src/Websocket/Websocket.php @@ -173,33 +173,23 @@ public function emit(string $event, $data): bool return false; } - /** @var Server $server */ + $payload = [ + 'sender' => $this->sender, + 'fds' => $fds, + 'broadcast' => $this->isBroadcast, + 'assigned' => $assigned, + 'event' => $event, + 'message' => $data, + ]; + + $result = true; $server = App::make(Server::class); - - if (!empty($server->taskworker)) { - /** @var Manager $manager */ - $manager = App::make(Manager::class); - $manager->pushMessage($server, [ - 'sender' => $this->sender, - 'fds' => $fds, - 'broadcast' => $this->isBroadcast, - 'assigned' => $assigned, - 'event' => $event, - 'message' => $data, - ]); - - $result = true; + if ($server->taskworker) { + App::make(Manager::class)->pushMessage($server, $payload); } else { $result = $server->task([ 'action' => static::PUSH_ACTION, - 'data' => [ - 'sender' => $this->sender, - 'fds' => $fds, - 'broadcast' => $this->isBroadcast, - 'assigned' => $assigned, - 'event' => $event, - 'message' => $data, - ], + 'data' => $payload ]); } diff --git a/tests/Websocket/WebsocketTest.php b/tests/Websocket/WebsocketTest.php index 967ac49d..9f1c5631 100644 --- a/tests/Websocket/WebsocketTest.php +++ b/tests/Websocket/WebsocketTest.php @@ -2,18 +2,19 @@ namespace SwooleTW\Http\Tests\Websocket; -use Illuminate\Container\Container; -use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; +use Mockery as m; use Illuminate\Http\Request; +use InvalidArgumentException; use Illuminate\Pipeline\Pipeline; +use SwooleTW\Http\Server\Manager; +use SwooleTW\Http\Tests\TestCase; +use Illuminate\Container\Container; use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\Config; -use InvalidArgumentException; -use Mockery as m; +use SwooleTW\Http\Websocket\Websocket; use SwooleTW\Http\Server\Facades\Server; -use SwooleTW\Http\Tests\TestCase; use SwooleTW\Http\Websocket\Rooms\RoomContract; -use SwooleTW\Http\Websocket\Websocket; +use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; class WebsocketTest extends TestCase { @@ -326,12 +327,15 @@ public function testEmit() ->times(3) ->andReturn([3, 4, 5]); + $server = m::mock('server'); + $server->taskworker = false; + App::shouldReceive('make') ->with(Server::class) ->once() - ->andReturnSelf(); + ->andReturn($server); - App::shouldReceive('task') + $server->shouldReceive('task') ->with([ 'action' => 'push', 'data' => [ @@ -355,6 +359,54 @@ public function testEmit() $this->assertFalse($websocket->getIsBroadcast()); } + public function testEmitInTaskWorker() + { + $sender = 1; + $to = [1, 2, 'a', 'b', 'c']; + $broadcast = true; + $room = m::mock(RoomContract::class); + $room->shouldReceive('getClients') + ->with(m::type('string')) + ->times(3) + ->andReturn([3, 4, 5]); + + $payload = [ + 'sender' => $sender, + 'fds' => [1, 2, 3, 4, 5], + 'broadcast' => $broadcast, + 'assigned' => true, + 'event' => $event = 'event', + 'message' => $data = 'data', + ]; + + $server = m::mock('server'); + $server->taskworker = true; + + $manager = m::mock(Manager::class); + $manager->shouldReceive('pushMessage') + ->with($server, $payload) + ->once(); + + App::shouldReceive('make') + ->with(Server::class) + ->once() + ->andReturn($server); + + App::shouldReceive('make') + ->with(Manager::class) + ->once() + ->andReturn($manager); + + $websocket = $this->getWebsocket($room); + $websocket->setSender($sender) + ->to($to) + ->broadcast() + ->emit($event, $data); + + $this->assertSame([], $websocket->getTo()); + $this->assertFalse($websocket->getIsBroadcast()); + } + public function testClose() { $fd = 1; From 8e2794464f907d8838580c79b1ace1ab21c132da Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 25 Aug 2019 21:31:39 +0800 Subject: [PATCH 138/161] Try to fix occasional non-array returned result in RedisRoom. --- src/Websocket/Rooms/RedisRoom.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Websocket/Rooms/RedisRoom.php b/src/Websocket/Rooms/RedisRoom.php index 2a5ba9e9..365b0b25 100644 --- a/src/Websocket/Rooms/RedisRoom.php +++ b/src/Websocket/Rooms/RedisRoom.php @@ -219,7 +219,10 @@ public function getValue(string $key, string $table) { $this->checkTable($table); - return $this->redis->smembers($this->getKey($key, $table)); + $result = $this->redis->smembers($this->getKey($key, $table)); + + // Try to fix occasional non-array returned result + return is_array($result) ? $result : []; } /** From 8b6ffc002a0afafa27ba204d6725a15e7d5a6ae9 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 25 Aug 2019 21:46:38 +0800 Subject: [PATCH 139/161] fix AuthenticateTest --- tests/Websocket/Middleware/AuthenticateTest.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/Websocket/Middleware/AuthenticateTest.php b/tests/Websocket/Middleware/AuthenticateTest.php index fcd5b4f9..d7dfa5be 100644 --- a/tests/Websocket/Middleware/AuthenticateTest.php +++ b/tests/Websocket/Middleware/AuthenticateTest.php @@ -12,14 +12,17 @@ class AuthenticateTest extends TestCase { public function testAuthenticate() { + $request = m::mock(Request::class); + $request->shouldReceive('setUserResolver') + ->once(); + $auth = m::mock(Auth::class); $auth->shouldReceive('authenticate') ->once() ->andReturn('user'); - - $request = m::mock(Request::class); - $request->shouldReceive('setUserResolver') - ->once(); + $auth->shouldReceive('setRequest') + ->with($request) + ->once(); $middleware = new Authenticate($auth); $middleware->handle($request, function ($next) { From dd568be0a932524993e69b61f457646fd3638d50 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 15 Sep 2019 21:44:12 +0800 Subject: [PATCH 140/161] make date format compatible for hot relooad in different operating systems --- src/HotReload/FSEventParser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HotReload/FSEventParser.php b/src/HotReload/FSEventParser.php index c0c35ef6..b37fbc8c 100644 --- a/src/HotReload/FSEventParser.php +++ b/src/HotReload/FSEventParser.php @@ -9,7 +9,7 @@ */ class FSEventParser { - protected const REGEX = '/^([\S+]{3}\s+[\S+]{3}\s+[\d+]{1,2}\s+[\d+]{2}:[\d+]{2}:{0,2}:[\d+]{2}:{0,2}\s+[\d+]{0,4})\s*(\/[\S+]*)\s+([\S+*\s+]*)/mi'; + protected const REGEX = '/^([\S+]{3}\s+[^\/]*)\s(\/[\S+]*)\s+([\S+*\s+]*)/mi'; protected const DATE = 1; protected const PATH = 2; From 9caffc74b838115d7a41c9b7c7f37db209108613 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 29 Sep 2019 19:51:24 +0800 Subject: [PATCH 141/161] add laravel 6.0 to composer.json and travis.yml --- .travis.yml | 2 ++ composer.json | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index d6af8a0c..a90e95ac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,8 @@ matrix: env: FRAMEWORK_VERSION=laravel/framework:5.7.* - php: 7.2 env: FRAMEWORK_VERSION=laravel/framework:5.8.* + - php: 7.2 + env: FRAMEWORK_VERSION=laravel/framework:6.0.* - php: 7.2 env: FRAMEWORK_VERSION=laravel/lumen-framework:5.5.* - php: 7.2 diff --git a/composer.json b/composer.json index 704f9890..dccf5daa 100644 --- a/composer.json +++ b/composer.json @@ -22,14 +22,14 @@ ], "require": { "php": "^7.2", - "illuminate/console": "~5.4", - "illuminate/contracts": "~5.4", - "illuminate/http": "~5.4", - "illuminate/support": "~5.4", + "illuminate/console": "~5.4|^6.0", + "illuminate/contracts": "~5.4|^6.0", + "illuminate/http": "~5.4|^6.0", + "illuminate/support": "~5.4|^6.0", "predis/predis": "^1.1" }, "require-dev": { - "laravel/lumen-framework": "~5.4", + "laravel/lumen-framework": "~5.4|^6.0", "phpunit/phpunit": "^7.5", "phpunit/php-code-coverage": "^6.1", "php-coveralls/php-coveralls": "^2.1", From eaa325e16bffd2b9da941a1dbf7429293bcc94d2 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 29 Sep 2019 20:13:09 +0800 Subject: [PATCH 142/161] fix composer.json for laravel 6 --- composer.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index dccf5daa..4e7f11f1 100644 --- a/composer.json +++ b/composer.json @@ -22,14 +22,14 @@ ], "require": { "php": "^7.2", - "illuminate/console": "~5.4|^6.0", - "illuminate/contracts": "~5.4|^6.0", - "illuminate/http": "~5.4|^6.0", - "illuminate/support": "~5.4|^6.0", + "illuminate/console": "~5.4|~6.0", + "illuminate/contracts": "~5.4|~6.0", + "illuminate/http": "~5.4|~6.0", + "illuminate/support": "~5.4|~6.0", "predis/predis": "^1.1" }, "require-dev": { - "laravel/lumen-framework": "~5.4|^6.0", + "laravel/lumen-framework": "~5.4|~6.0", "phpunit/phpunit": "^7.5", "phpunit/php-code-coverage": "^6.1", "php-coveralls/php-coveralls": "^2.1", From dfbc1f832a821ccfde4f515fc1278bc02d596a4c Mon Sep 17 00:00:00 2001 From: Gene C <1152573+geneccx@users.noreply.github.com> Date: Wed, 6 Nov 2019 14:40:02 -0800 Subject: [PATCH 143/161] Fix unqueueing cookies This seems to have changed in Laravel 6. The key is just the array index of the queued cookie, but `unqueue` takes the name of the cookie, and as a result, no cookies are actually unqueued. --- src/Server/Resetters/ResetCookie.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Server/Resetters/ResetCookie.php b/src/Server/Resetters/ResetCookie.php index 85da6cba..28d26662 100644 --- a/src/Server/Resetters/ResetCookie.php +++ b/src/Server/Resetters/ResetCookie.php @@ -20,7 +20,7 @@ public function handle(Container $app, Sandbox $sandbox) if (isset($app['cookie'])) { $cookies = $app->make('cookie'); foreach ($cookies->getQueuedCookies() as $key => $value) { - $cookies->unqueue($key); + $cookies->unqueue($value->getName()); } } From 947a21be17679bf5693450e8ff1e16aca9df55bc Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 1 Dec 2019 15:54:17 +0800 Subject: [PATCH 144/161] extract resetters tests and fix cookie resetter test --- tests/Server/Resetters/BindRequestTest.php | 30 +++ tests/Server/Resetters/ClearInstanceTest.php | 29 ++ .../Resetters/RebindKernelContainerTest.php | 31 +++ .../Resetters/RebindRouterContainerTest.php | 79 ++++++ .../Resetters/RebindViewContainerTest.php | 27 ++ tests/Server/Resetters/ResetConfigTest.php | 28 ++ tests/Server/Resetters/ResetCookieTest.php | 37 +++ tests/Server/Resetters/ResetProvidersTest.php | 54 ++++ tests/Server/Resetters/ResetSessionTest.php | 29 ++ tests/Server/ResettersTest.php | 248 ------------------ 10 files changed, 344 insertions(+), 248 deletions(-) create mode 100644 tests/Server/Resetters/BindRequestTest.php create mode 100644 tests/Server/Resetters/ClearInstanceTest.php create mode 100644 tests/Server/Resetters/RebindKernelContainerTest.php create mode 100644 tests/Server/Resetters/RebindRouterContainerTest.php create mode 100644 tests/Server/Resetters/RebindViewContainerTest.php create mode 100644 tests/Server/Resetters/ResetConfigTest.php create mode 100644 tests/Server/Resetters/ResetCookieTest.php create mode 100644 tests/Server/Resetters/ResetProvidersTest.php create mode 100644 tests/Server/Resetters/ResetSessionTest.php delete mode 100644 tests/Server/ResettersTest.php diff --git a/tests/Server/Resetters/BindRequestTest.php b/tests/Server/Resetters/BindRequestTest.php new file mode 100644 index 00000000..68816b6f --- /dev/null +++ b/tests/Server/Resetters/BindRequestTest.php @@ -0,0 +1,30 @@ +shouldReceive('getRequest') + ->once() + ->andReturn($request); + + $container = new Container; + + $resetter = new BindRequest; + $app = $resetter->handle($container, $sandbox); + + $this->assertSame($request, $app->make('request')); + } +} diff --git a/tests/Server/Resetters/ClearInstanceTest.php b/tests/Server/Resetters/ClearInstanceTest.php new file mode 100644 index 00000000..2b93c265 --- /dev/null +++ b/tests/Server/Resetters/ClearInstanceTest.php @@ -0,0 +1,29 @@ +shouldReceive('getConfig->get') + ->with('swoole_http.instances', []) + ->once() + ->andReturn(['foo']); + + $container = new Container; + $container->instance('foo', m::mock('foo')); + + $resetter = new ClearInstances; + $app = $resetter->handle($container, $sandbox); + + $this->assertFalse($app->bound('foo')); + } +} diff --git a/tests/Server/Resetters/RebindKernelContainerTest.php b/tests/Server/Resetters/RebindKernelContainerTest.php new file mode 100644 index 00000000..c4c66639 --- /dev/null +++ b/tests/Server/Resetters/RebindKernelContainerTest.php @@ -0,0 +1,31 @@ +shouldReceive('isLaravel') + ->once() + ->andReturn(true); + + $kernel = m::mock(Kernel::class); + + $container = new Container; + $container->instance(Kernel::class, $kernel); + + $resetter = new RebindKernelContainer; + $app = $resetter->handle($container, $sandbox); + + $this->assertSame($app, $app->make(Kernel::class)->app); + } +} diff --git a/tests/Server/Resetters/RebindRouterContainerTest.php b/tests/Server/Resetters/RebindRouterContainerTest.php new file mode 100644 index 00000000..1f3834a6 --- /dev/null +++ b/tests/Server/Resetters/RebindRouterContainerTest.php @@ -0,0 +1,79 @@ +shouldReceive('isLaravel') + ->once() + ->andReturn(true); + $sandbox->shouldReceive('getRequest') + ->once() + ->andReturn($request); + + $router = m::mock('router'); + + $container = new Container; + $container->instance('router', $router); + + $route = m::mock('route'); + $route->controller = 'controller'; + $route->shouldReceive('setContainer') + ->once() + ->with($container); + + $routes = m::mock('routes'); + $routes->shouldReceive('match') + ->once() + ->with($request) + ->andReturn($route); + + $router->routes = $routes; + + $resetter = new RebindRouterContainer; + $app = $resetter->handle($container, $sandbox); + + $this->assertSame($app, $router->container); + } + + public function testRebindLumenRouterContainer() + { + $sandbox = m::mock(Sandbox::class); + $sandbox->shouldReceive('isLaravel') + ->once() + ->andReturn(false); + + $router = m::mock('router'); + + $container = m::mock(Container::class); + $container->shouldReceive('offsetSet') + ->with('router', $router) + ->once() + ->andReturnSelf(); + $container->shouldReceive('offsetGet') + ->with('router') + ->andReturn($router); + $container->router = $router; + + $this->mockMethod('property_exists', function () { + return true; + }, 'SwooleTW\Http\Server\Resetters'); + + $resetter = new RebindRouterContainer; + $app = $resetter->handle($container, $sandbox); + + $this->assertSame($app, $app->router->app); + } +} diff --git a/tests/Server/Resetters/RebindViewContainerTest.php b/tests/Server/Resetters/RebindViewContainerTest.php new file mode 100644 index 00000000..c418ae36 --- /dev/null +++ b/tests/Server/Resetters/RebindViewContainerTest.php @@ -0,0 +1,27 @@ +instance('view', $view); + + $resetter = new RebindViewContainer; + $app = $resetter->handle($container, $sandbox); + + $this->assertSame($app, $app->make('view')->container); + $this->assertSame($app, $app->make('view')->shared['app']); + } +} diff --git a/tests/Server/Resetters/ResetConfigTest.php b/tests/Server/Resetters/ResetConfigTest.php new file mode 100644 index 00000000..cb74ffe0 --- /dev/null +++ b/tests/Server/Resetters/ResetConfigTest.php @@ -0,0 +1,28 @@ +shouldReceive('getConfig') + ->once() + ->andReturn($config); + + $container = new Container; + $resetter = new ResetConfig; + $app = $resetter->handle($container, $sandbox); + + $this->assertSame(get_class($config), get_class($app->make('config'))); + } +} diff --git a/tests/Server/Resetters/ResetCookieTest.php b/tests/Server/Resetters/ResetCookieTest.php new file mode 100644 index 00000000..1bec5ff3 --- /dev/null +++ b/tests/Server/Resetters/ResetCookieTest.php @@ -0,0 +1,37 @@ +shouldReceive('getName') + ->once() + ->andReturn('foo'); + + $cookies = m::mock('cookies'); + $cookies->shouldReceive('getQueuedCookies') + ->once() + ->andReturn([$cookie]); + $cookies->shouldReceive('unqueue') + ->once() + ->with('foo'); + + $sandbox = m::mock(Sandbox::class); + + $container = new Container; + $container->instance('cookie', $cookies); + + $resetter = new ResetCookie; + $app = $resetter->handle($container, $sandbox); + } +} diff --git a/tests/Server/Resetters/ResetProvidersTest.php b/tests/Server/Resetters/ResetProvidersTest.php new file mode 100644 index 00000000..dcd2bdcc --- /dev/null +++ b/tests/Server/Resetters/ResetProvidersTest.php @@ -0,0 +1,54 @@ +shouldReceive('register') + ->once(); + $provider->shouldReceive('boot') + ->once(); + + $sandbox = m::mock(Sandbox::class); + $sandbox->shouldReceive('getProviders') + ->once() + ->andReturn([$provider]); + + $this->mockMethod('method_exists', function () { + return true; + }, 'SwooleTW\Http\Server\Resetters'); + + $container = new Container; + $resetter = new ResetProviders; + $app = $resetter->handle($container, $sandbox); + + $reflector = new \ReflectionProperty(TestProvider::class, 'app'); + $reflector->setAccessible(true); + + $this->assertSame($app, $reflector->getValue($provider)); + } +} + +class TestProvider extends ServiceProvider +{ + public function register() + { + // + } + + public function boot() + { + // + } +} + diff --git a/tests/Server/Resetters/ResetSessionTest.php b/tests/Server/Resetters/ResetSessionTest.php new file mode 100644 index 00000000..178be0f4 --- /dev/null +++ b/tests/Server/Resetters/ResetSessionTest.php @@ -0,0 +1,29 @@ +shouldReceive('flush') + ->once(); + $session->shouldReceive('regenerate') + ->once(); + + $sandbox = m::mock(Sandbox::class); + + $container = new Container; + $container->instance('session', $session); + + $resetter = new ResetSession; + $app = $resetter->handle($container, $sandbox); + } +} diff --git a/tests/Server/ResettersTest.php b/tests/Server/ResettersTest.php deleted file mode 100644 index a90d2283..00000000 --- a/tests/Server/ResettersTest.php +++ /dev/null @@ -1,248 +0,0 @@ -shouldReceive('getRequest') - ->once() - ->andReturn($request); - - $container = new Container; - - $resetter = new BindRequest; - $app = $resetter->handle($container, $sandbox); - - $this->assertSame($request, $app->make('request')); - } - - public function testClearInstance() - { - $sandbox = m::mock(Sandbox::class); - $sandbox->shouldReceive('getConfig->get') - ->with('swoole_http.instances', []) - ->once() - ->andReturn(['foo']); - - $container = new Container; - $container->instance('foo', m::mock('foo')); - - $resetter = new ClearInstances; - $app = $resetter->handle($container, $sandbox); - - $this->assertFalse($app->bound('foo')); - } - - public function testRebindKernelContainer() - { - $sandbox = m::mock(Sandbox::class); - $sandbox->shouldReceive('isLaravel') - ->once() - ->andReturn(true); - - $kernel = m::mock(Kernel::class); - - $container = new Container; - $container->instance(Kernel::class, $kernel); - - $resetter = new RebindKernelContainer; - $app = $resetter->handle($container, $sandbox); - - $this->assertSame($app, $app->make(Kernel::class)->app); - } - - public function testRebindLaravelRouterContainer() - { - $request = m::mock(Request::class); - - $sandbox = m::mock(Sandbox::class); - $sandbox->shouldReceive('isLaravel') - ->once() - ->andReturn(true); - $sandbox->shouldReceive('getRequest') - ->once() - ->andReturn($request); - - $router = m::mock('router'); - - $container = new Container; - $container->instance('router', $router); - - $route = m::mock('route'); - $route->controller = 'controller'; - $route->shouldReceive('setContainer') - ->once() - ->with($container); - - $routes = m::mock('routes'); - $routes->shouldReceive('match') - ->once() - ->with($request) - ->andReturn($route); - - $router->routes = $routes; - - $resetter = new RebindRouterContainer; - $app = $resetter->handle($container, $sandbox); - - $this->assertSame($app, $router->container); - } - - public function testRebindLumenRouterContainer() - { - $sandbox = m::mock(Sandbox::class); - $sandbox->shouldReceive('isLaravel') - ->once() - ->andReturn(false); - - $router = m::mock('router'); - - $container = m::mock(Container::class); - $container->shouldReceive('offsetSet') - ->with('router', $router) - ->once() - ->andReturnSelf(); - $container->shouldReceive('offsetGet') - ->with('router') - ->andReturn($router); - $container->router = $router; - - $this->mockMethod('property_exists', function () { - return true; - }, 'SwooleTW\Http\Server\Resetters'); - - $resetter = new RebindRouterContainer; - $app = $resetter->handle($container, $sandbox); - - $this->assertSame($app, $app->router->app); - } - - public function testRebindViewContainer() - { - $sandbox = m::mock(Sandbox::class); - $view = m::mock('view'); - - $container = new Container; - $container->instance('view', $view); - - $resetter = new RebindViewContainer; - $app = $resetter->handle($container, $sandbox); - - $this->assertSame($app, $app->make('view')->container); - $this->assertSame($app, $app->make('view')->shared['app']); - } - - public function testResetConfig() - { - $config = m::mock(ConfigContract::class); - $sandbox = m::mock(Sandbox::class); - $sandbox->shouldReceive('getConfig') - ->once() - ->andReturn($config); - - $container = new Container; - $resetter = new ResetConfig; - $app = $resetter->handle($container, $sandbox); - - $this->assertSame(get_class($config), get_class($app->make('config'))); - } - - public function testResetCookie() - { - $cookies = m::mock('cookies'); - $cookies->shouldReceive('getQueuedCookies') - ->once() - ->andReturn(['foo']); - $cookies->shouldReceive('unqueue') - ->once() - ->with('foo'); - - $sandbox = m::mock(Sandbox::class); - - $container = new Container; - $container->instance('cookie', $cookies); - - $resetter = new ResetCookie; - $app = $resetter->handle($container, $sandbox); - } - - public function testResetSession() - { - $session = m::mock('session'); - $session->shouldReceive('flush') - ->once(); - $session->shouldReceive('regenerate') - ->once(); - - $sandbox = m::mock(Sandbox::class); - - $container = new Container; - $container->instance('session', $session); - - $resetter = new ResetSession; - $app = $resetter->handle($container, $sandbox); - } - - public function testResetProviders() - { - $provider = m::mock(TestProvider::class); - $provider->shouldReceive('register') - ->once(); - $provider->shouldReceive('boot') - ->once(); - - $sandbox = m::mock(Sandbox::class); - $sandbox->shouldReceive('getProviders') - ->once() - ->andReturn([$provider]); - - $this->mockMethod('method_exists', function () { - return true; - }, 'SwooleTW\Http\Server\Resetters'); - - $container = new Container; - $resetter = new ResetProviders; - $app = $resetter->handle($container, $sandbox); - - $reflector = new \ReflectionProperty(TestProvider::class, 'app'); - $reflector->setAccessible(true); - - $this->assertSame($app, $reflector->getValue($provider)); - } -} - -class TestProvider extends ServiceProvider -{ - public function register() - { - // - } - - public function boot() - { - // - } -} From e0e4c38b1ad4520da5fd31df3eb7596b97846427 Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 1 Dec 2019 16:34:33 +0800 Subject: [PATCH 145/161] mock env helper function in tests --- tests/Coroutine/ConnectorFactoryTest.php | 6 ++++++ tests/Task/QueueFactoryTest.php | 6 ++++++ tests/TestCase.php | 11 +++++++++++ 3 files changed, 23 insertions(+) diff --git a/tests/Coroutine/ConnectorFactoryTest.php b/tests/Coroutine/ConnectorFactoryTest.php index a18f9d83..27e70a4a 100644 --- a/tests/Coroutine/ConnectorFactoryTest.php +++ b/tests/Coroutine/ConnectorFactoryTest.php @@ -14,6 +14,12 @@ */ class ConnectorFactoryTest extends TestCase { + public function setUp() + { + parent::setUp(); + $this->mockEnv('Laravel\Lumen'); + } + public function testItHasNeededStubByVersion() { $version = FW::version(); diff --git a/tests/Task/QueueFactoryTest.php b/tests/Task/QueueFactoryTest.php index c41ee211..66cae40b 100644 --- a/tests/Task/QueueFactoryTest.php +++ b/tests/Task/QueueFactoryTest.php @@ -15,6 +15,12 @@ */ class QueueFactoryTest extends TestCase { + public function setUp() + { + parent::setUp(); + $this->mockEnv('Laravel\Lumen'); + } + public function testItHasNeededStubByVersion() { $version = FW::version(); diff --git a/tests/TestCase.php b/tests/TestCase.php index 1e666707..28f32301 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -34,4 +34,15 @@ protected function mockMethod($name, \Closure $function, $namespace = null) $mock = $builder->build(); $mock->enable(); } + + protected function mockEnv(string $namespace, array $variables = []) + { + $this->mockMethod('env', function ($key, $value = null) use ($variables) { + if (array_key_exists($key, $variables)) { + return $variables[$key]; + } + + return null; + }, $namespace); + } } From 74f0d2fdc52cf4a5a4655db8d00b3938a3e91209 Mon Sep 17 00:00:00 2001 From: Bill Li <21023027+lilianjin@users.noreply.github.com> Date: Mon, 27 Jan 2020 23:38:13 +0800 Subject: [PATCH 146/161] There is no session option on 5.8, so fix it --- src/Websocket/Middleware/StartSession.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Websocket/Middleware/StartSession.php b/src/Websocket/Middleware/StartSession.php index a487f237..6be32c6d 100644 --- a/src/Websocket/Middleware/StartSession.php +++ b/src/Websocket/Middleware/StartSession.php @@ -86,6 +86,6 @@ public function getSession(Request $request) */ protected function sessionConfigured() { - return Arr::get($this->manager->getSessionConfig(), 'session') !== null; + return ! is_null($this->manager->getSessionConfig()['driver'] ?? null); } } From 3cf0cd997d0503f1cc73c8d330818b81dadd6f95 Mon Sep 17 00:00:00 2001 From: Gene Chen Date: Tue, 3 Mar 2020 13:17:17 -0800 Subject: [PATCH 147/161] Clear context after disabling sandbox --- src/Server/Sandbox.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Server/Sandbox.php b/src/Server/Sandbox.php index 5bf878e1..1fcad3bd 100644 --- a/src/Server/Sandbox.php +++ b/src/Server/Sandbox.php @@ -324,8 +324,8 @@ public function enable() */ public function disable() { - Context::clear(); $this->setInstance($this->getBaseApp()); + Context::clear(); } /** From 5a5c359343ca1b5a99502ad9a6ff869ed3278176 Mon Sep 17 00:00:00 2001 From: Mahdi Youseftabar Date: Tue, 10 Mar 2020 03:52:09 +0330 Subject: [PATCH 148/161] change status() to getStatusCode() laravel response has getStatusCode in all response objects but baniry response has not status() method fixes !289 --- src/Server/AccessOutput.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Server/AccessOutput.php b/src/Server/AccessOutput.php index 08056981..08de5046 100644 --- a/src/Server/AccessOutput.php +++ b/src/Server/AccessOutput.php @@ -41,7 +41,7 @@ public function log(Request $request, Response $response): void $method = $request->method(); $agent = $request->userAgent(); $date = $this->date($response->getDate()); - $status = $response->status(); + $status = $response->getStatusCode(); $style = $this->style($status); $this->output->writeln( @@ -68,4 +68,4 @@ protected function style(int $status): string { return $status !== Response::HTTP_OK ? 'error' : 'info'; } -} \ No newline at end of file +} From 7e815ae999ba10a2dfe31379fb1be85e2a82aefa Mon Sep 17 00:00:00 2001 From: Dmitry Date: Tue, 10 Mar 2020 20:05:29 +0300 Subject: [PATCH 149/161] Update composer.json --- composer.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 4e7f11f1..8946791e 100644 --- a/composer.json +++ b/composer.json @@ -22,14 +22,14 @@ ], "require": { "php": "^7.2", - "illuminate/console": "~5.4|~6.0", - "illuminate/contracts": "~5.4|~6.0", - "illuminate/http": "~5.4|~6.0", - "illuminate/support": "~5.4|~6.0", + "illuminate/console": "~5.4|~6.0|~7.0", + "illuminate/contracts": "~5.4|~6.0|~7.0", + "illuminate/http": "~5.4|~6.0|~7.0", + "illuminate/support": "~5.4|~6.0|~7.0", "predis/predis": "^1.1" }, "require-dev": { - "laravel/lumen-framework": "~5.4|~6.0", + "laravel/lumen-framework": "~5.4|~6.0|~7.0", "phpunit/phpunit": "^7.5", "phpunit/php-code-coverage": "^6.1", "php-coveralls/php-coveralls": "^2.1", From 7db04ae00f297985efa72869186408d065049611 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=81=A5?= Date: Thu, 7 May 2020 10:42:14 +0800 Subject: [PATCH 150/161] fix 'swoole_set_process_name' not found error on cygwin platform --- src/Helpers/OS.php | 9 ++++++++- src/Server/Manager.php | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Helpers/OS.php b/src/Helpers/OS.php index d1541639..7a22a6fb 100644 --- a/src/Helpers/OS.php +++ b/src/Helpers/OS.php @@ -30,6 +30,13 @@ final class OS */ public const WIN = 'win'; + /** + * Cygwin + * + * @const string + */ + public const CYGWIN = 'cyg'; + /** * Returns true if current OS in types * @@ -51,4 +58,4 @@ public static function current(): string { return Str::substr(Str::lower(PHP_OS), 0, 3); } -} \ No newline at end of file +} diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 0f751cf6..35e0c9c7 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -353,7 +353,7 @@ protected function clearCache() protected function setProcessName($process) { // MacOS doesn't support modifying process name. - if (OS::is(OS::MAC_OS) || $this->isInTesting()) { + if (OS::is(OS::MAC_OS, OS::CYGWIN) || $this->isInTesting()) { return; } $serverName = 'swoole_http_server'; From 1d5aef72754fdee94779e9ba761a51e89567d33a Mon Sep 17 00:00:00 2001 From: Joe Jiang Date: Mon, 11 May 2020 18:55:36 +0800 Subject: [PATCH 151/161] fix: change MimeType::get condition If pass empty string to this function, It should not return all mimes. --- src/Helpers/MimeType.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Helpers/MimeType.php b/src/Helpers/MimeType.php index 5edab5cf..7132b629 100644 --- a/src/Helpers/MimeType.php +++ b/src/Helpers/MimeType.php @@ -805,7 +805,7 @@ public static function from($filename) */ public static function get($extension = null) { - return $extension ? self::getMimeTypeFromExtension($extension) : self::$mimes; + return isset($extension) ? self::getMimeTypeFromExtension($extension) : self::$mimes; } /** From 42af646f484862c0f9e2b52eea67568c6eb57070 Mon Sep 17 00:00:00 2001 From: Joe Jiang Date: Mon, 11 May 2020 18:58:37 +0800 Subject: [PATCH 152/161] feat: Add test for empty string to MimeType::get --- tests/Helpers/MimeTypeTest.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/Helpers/MimeTypeTest.php b/tests/Helpers/MimeTypeTest.php index fe8c031d..1dd9e7dd 100644 --- a/tests/Helpers/MimeTypeTest.php +++ b/tests/Helpers/MimeTypeTest.php @@ -14,6 +14,14 @@ public function testGet() $this->assertEquals($mimetype, 'text/css'); } + + public function testGetWithEmptyString() + { + $extension = ''; + $mimetype = MimeType::get($extension); + + $this->assertEquals($mimetype, 'application/octet-stream'); + } public function testFrom() { From 9bce1c29e11a5a1bf6a7f93fc5d40cf42e612a00 Mon Sep 17 00:00:00 2001 From: Linc70J <31087557+Linc70J@users.noreply.github.com> Date: Wed, 13 May 2020 15:48:21 +0800 Subject: [PATCH 153/161] fix handle_static_files config path fix handle_static_files config path --- src/Server/Manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 0f751cf6..ec418120 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -204,7 +204,7 @@ public function onRequest($swooleRequest, $swooleResponse) $this->resetOnRequest(); $sandbox = $this->app->make(Sandbox::class); - $handleStatic = $this->container->make('config')->get('swoole_http.handle_static_files', true); + $handleStatic = $this->container->make('config')->get('swoole_http.server.handle_static_files', true); $publicPath = $this->container->make('config')->get('swoole_http.server.public_path', base_path('public')); try { From e9de2aa7c1bba2c344c59de82a6c94b631174b51 Mon Sep 17 00:00:00 2001 From: netdown Date: Thu, 28 May 2020 12:52:37 +0200 Subject: [PATCH 154/161] Replace FatalThrowableError --- src/Server/Manager.php | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/Server/Manager.php b/src/Server/Manager.php index 0f751cf6..e6505381 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -23,7 +23,7 @@ use Symfony\Component\Console\Output\ConsoleOutput; use SwooleTW\Http\Concerns\InteractsWithSwooleQueue; use SwooleTW\Http\Concerns\InteractsWithSwooleTable; -use Symfony\Component\Debug\Exception\FatalThrowableError; +use Symfony\Component\ErrorHandler\Error\FatalError; /** * Class Manager @@ -411,7 +411,23 @@ public function logServerError(Throwable $e) protected function normalizeException(Throwable $e) { if (! $e instanceof Exception) { - $e = new FatalThrowableError($e); + if ($e instanceof \ParseError) { + $severity = E_PARSE; + } elseif ($e instanceof \TypeError) { + $severity = E_RECOVERABLE_ERROR; + } else { + $severity = E_ERROR; + } + + //error_get_last() syntax + $error = [ + 'type' => $severity, + 'message' => $e->getMessage(), + 'file' => $e->getFile(), + 'line' => $e->getLine(), + ]; + + $e = new FatalError($e->getMessage(), $e->getCode(), $error, null, true, $e->getTrace()); } return $e; From c61511d9918f2440bfbd106d3e466637a5aed315 Mon Sep 17 00:00:00 2001 From: netdown Date: Mon, 8 Jun 2020 13:47:40 +0200 Subject: [PATCH 155/161] Update Websocket.php --- src/Websocket/Websocket.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Websocket/Websocket.php b/src/Websocket/Websocket.php index aa9c45bb..41f05494 100644 --- a/src/Websocket/Websocket.php +++ b/src/Websocket/Websocket.php @@ -170,6 +170,7 @@ public function emit(string $event, $data): bool // that means trying to emit to a non-existing room // skip it directly instead of pushing to a task queue if (empty($fds) && $assigned) { + $this->reset(); return false; } From d80e47f013dc71b277661971be47109a364c9664 Mon Sep 17 00:00:00 2001 From: netdown Date: Mon, 8 Jun 2020 13:59:41 +0200 Subject: [PATCH 156/161] Restore other changes --- src/Server/Manager.php | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/src/Server/Manager.php b/src/Server/Manager.php index e6505381..0f751cf6 100644 --- a/src/Server/Manager.php +++ b/src/Server/Manager.php @@ -23,7 +23,7 @@ use Symfony\Component\Console\Output\ConsoleOutput; use SwooleTW\Http\Concerns\InteractsWithSwooleQueue; use SwooleTW\Http\Concerns\InteractsWithSwooleTable; -use Symfony\Component\ErrorHandler\Error\FatalError; +use Symfony\Component\Debug\Exception\FatalThrowableError; /** * Class Manager @@ -411,23 +411,7 @@ public function logServerError(Throwable $e) protected function normalizeException(Throwable $e) { if (! $e instanceof Exception) { - if ($e instanceof \ParseError) { - $severity = E_PARSE; - } elseif ($e instanceof \TypeError) { - $severity = E_RECOVERABLE_ERROR; - } else { - $severity = E_ERROR; - } - - //error_get_last() syntax - $error = [ - 'type' => $severity, - 'message' => $e->getMessage(), - 'file' => $e->getFile(), - 'line' => $e->getLine(), - ]; - - $e = new FatalError($e->getMessage(), $e->getCode(), $error, null, true, $e->getTrace()); + $e = new FatalThrowableError($e); } return $e; From fda0a045e62690b6fd0d9f479b1267cdcc548839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=BE=E6=98=AF=E7=84=B6?= <38133602+icecho@users.noreply.github.com> Date: Tue, 16 Jun 2020 09:55:12 +0800 Subject: [PATCH 157/161] fix a spelling error --- src/Websocket/Rooms/RedisRoom.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Websocket/Rooms/RedisRoom.php b/src/Websocket/Rooms/RedisRoom.php index 365b0b25..46ef7e9b 100644 --- a/src/Websocket/Rooms/RedisRoom.php +++ b/src/Websocket/Rooms/RedisRoom.php @@ -149,7 +149,7 @@ public function addValue($key, array $values, string $table) } /** - * Remove value from reddis. + * Remove value from redis. * * @param $key * @param array $values From bb7b89089e786a527ffc5b68964a69de7ac78068 Mon Sep 17 00:00:00 2001 From: Haven Shen Date: Thu, 23 Jul 2020 14:32:22 +0800 Subject: [PATCH 158/161] modify Dumper.php file class name. --- src/Helpers/Dumper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Helpers/Dumper.php b/src/Helpers/Dumper.php index c4ffb68b..c1087e93 100644 --- a/src/Helpers/Dumper.php +++ b/src/Helpers/Dumper.php @@ -6,7 +6,7 @@ use Symfony\Component\VarDumper\Dumper\CliDumper; use Symfony\Component\VarDumper\Dumper\HtmlDumper; -class VarDumper +class Dumper { protected static $cloner; From 7dc0963662b0fa79258e146d40e379966cc2a84b Mon Sep 17 00:00:00 2001 From: Dawid Janik Date: Tue, 8 Sep 2020 23:14:26 +0200 Subject: [PATCH 159/161] Add Laravel 8 support. --- composer.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 8946791e..931c8ecb 100644 --- a/composer.json +++ b/composer.json @@ -22,14 +22,14 @@ ], "require": { "php": "^7.2", - "illuminate/console": "~5.4|~6.0|~7.0", - "illuminate/contracts": "~5.4|~6.0|~7.0", - "illuminate/http": "~5.4|~6.0|~7.0", - "illuminate/support": "~5.4|~6.0|~7.0", + "illuminate/console": "~5.4|~6.0|~7.0|~8.0", + "illuminate/contracts": "~5.4|~6.0|~7.0|~8.0", + "illuminate/http": "~5.4|~6.0|~7.0|~8.0", + "illuminate/support": "~5.4|~6.0|~7.0|~8.0", "predis/predis": "^1.1" }, "require-dev": { - "laravel/lumen-framework": "~5.4|~6.0|~7.0", + "laravel/lumen-framework": "~5.4|~6.0|~7.0|~8.0", "phpunit/phpunit": "^7.5", "phpunit/php-code-coverage": "^6.1", "php-coveralls/php-coveralls": "^2.1", From 3a93e92c8b8ad5eed8bbdf4398faa22bdef48b4f Mon Sep 17 00:00:00 2001 From: Victor Gazotti Date: Thu, 1 Oct 2020 18:35:48 -0300 Subject: [PATCH 160/161] Add auth to the pre_resolved as default As many apps uses the **auth** instances, it could be usefull if auth was cleaned at every request as default. I do this change in every new installation of this package for example. --- config/swoole_http.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/swoole_http.php b/config/swoole_http.php index f73a2c59..150e680f 100644 --- a/config/swoole_http.php +++ b/config/swoole_http.php @@ -81,7 +81,7 @@ 'pre_resolved' => [ 'view', 'files', 'session', 'session.store', 'routes', 'db', 'db.factory', 'cache', 'cache.store', 'config', 'cookie', - 'encrypter', 'hash', 'router', 'translator', 'url', 'log', + 'encrypter', 'hash', 'router', 'translator', 'url', 'log', 'auth', ], /* From b3e824ade8141409543a41976108b275d4a79d3c Mon Sep 17 00:00:00 2001 From: m3m0r7 Date: Tue, 24 Nov 2020 15:05:27 +0900 Subject: [PATCH 161/161] Fix invalid SWOOLE_PROCESS value --- src/Server/helpers.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Server/helpers.php b/src/Server/helpers.php index 51dd9fcb..f9c43ba8 100644 --- a/src/Server/helpers.php +++ b/src/Server/helpers.php @@ -18,5 +18,5 @@ function swoole_cpu_num(): int } if (! defined('SWOOLE_PROCESS')) { - define('SWOOLE_PROCESS', 3); + define('SWOOLE_PROCESS', 2); }