├── LICENSE.txt
├── config
├── .htaccess
├── extra
│ └── workerman.php
├── common.php
├── command.php
├── route.php
├── tags.php
├── database.php
└── config.php
├── extend
└── .gitignore
├── runtime
└── .gitignore
├── public
├── static
│ └── .gitignore
├── robots.txt
├── favicon.ico
├── .htaccess
├── router.php
└── index.php
├── .gitignore
├── server.bat
├── vendor
├── topthink
│ ├── think-installer
│ │ ├── .gitignore
│ │ ├── composer.json
│ │ └── src
│ │ │ ├── Plugin.php
│ │ │ ├── ThinkFramework.php
│ │ │ ├── ThinkTesting.php
│ │ │ └── ThinkExtend.php
│ └── think-worker
│ │ ├── composer.json
│ │ ├── README.md
│ │ ├── src
│ │ └── Server.php
│ │ └── LICENSE
├── workerman
│ ├── workerman
│ │ ├── .gitignore
│ │ ├── Lib
│ │ │ ├── Constants.php
│ │ │ └── Timer.php
│ │ ├── composer.json
│ │ ├── MIT-LICENSE.txt
│ │ ├── Protocols
│ │ │ ├── Frame.php
│ │ │ ├── ProtocolInterface.php
│ │ │ ├── Text.php
│ │ │ └── Http
│ │ │ │ └── mime.types
│ │ ├── Events
│ │ │ ├── EventInterface.php
│ │ │ ├── Ev.php
│ │ │ ├── Event.php
│ │ │ ├── Libevent.php
│ │ │ └── Select.php
│ │ ├── Connection
│ │ │ ├── ConnectionInterface.php
│ │ │ ├── UdpConnection.php
│ │ │ └── AsyncTcpConnection.php
│ │ ├── Autoloader.php
│ │ └── WebServer.php
│ └── workerman-for-win
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── Lib
│ │ ├── Constants.php
│ │ └── Timer.php
│ │ ├── composer.json
│ │ ├── MIT-LICENSE.txt
│ │ ├── Protocols
│ │ ├── Frame.php
│ │ ├── ProtocolInterface.php
│ │ ├── Text.php
│ │ └── Http
│ │ │ └── mime.types
│ │ ├── Events
│ │ ├── EventInterface.php
│ │ ├── Ev.php
│ │ ├── Event.php
│ │ ├── Libevent.php
│ │ └── Select.php
│ │ ├── Connection
│ │ ├── ConnectionInterface.php
│ │ ├── UdpConnection.php
│ │ ├── AsyncUdpConnection.php
│ │ └── AsyncTcpConnection.php
│ │ ├── Autoloader.php
│ │ └── WebServer.php
├── autoload.php
└── composer
│ ├── autoload_classmap.php
│ ├── autoload_namespaces.php
│ ├── autoload_psr4.php
│ ├── LICENSE
│ ├── autoload_static.php
│ ├── autoload_real.php
│ └── installed.json
├── server.php
├── application
├── index
│ ├── view
│ │ └── index
│ │ │ └── connect.html
│ └── controller
│ │ └── Index.php
└── push
│ └── controller
│ ├── Push.php
│ ├── User.php
│ └── Worker.php
├── composer.json
├── think
└── README.md
/LICENSE.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/config/.htaccess:
--------------------------------------------------------------------------------
1 | deny from all
--------------------------------------------------------------------------------
/extend/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/runtime/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/public/static/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | composer.lock
3 | *.log
4 | thinkphp
5 |
--------------------------------------------------------------------------------
/server.bat:
--------------------------------------------------------------------------------
1 | echo "Do not close this window "
2 | php server.php start
3 | pause
--------------------------------------------------------------------------------
/vendor/topthink/think-installer/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea
2 | composer.lock
3 | /vendor
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ctfang/push-server/master/public/favicon.ico
--------------------------------------------------------------------------------
/vendor/workerman/workerman/.gitignore:
--------------------------------------------------------------------------------
1 | logs
2 | .buildpath
3 | .project
4 | .settings
5 | .idea
--------------------------------------------------------------------------------
/vendor/workerman/workerman-for-win/.gitignore:
--------------------------------------------------------------------------------
1 | .project
2 | .buildpath
3 | .settings/org.eclipse.php.core.prefs
--------------------------------------------------------------------------------
/vendor/autoload.php:
--------------------------------------------------------------------------------
1 |
2 | Options +FollowSymlinks -Multiviews
3 | RewriteEngine On
4 |
5 | RewriteCond %{REQUEST_FILENAME} !-d
6 | RewriteCond %{REQUEST_FILENAME} !-f
7 | RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
8 |
9 |
--------------------------------------------------------------------------------
/config/extra/workerman.php:
--------------------------------------------------------------------------------
1 | 'websocket://push.pparking.app:2347',
11 | // 内部通讯监听
12 | 'text'=>'Text://push.pparking.app:23478',
13 | );
14 |
--------------------------------------------------------------------------------
/vendor/topthink/think-worker/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "topthink/think-worker",
3 | "description": "workerman extend for thinkphp5",
4 | "license": "Apache-2.0",
5 | "authors": [
6 | {
7 | "name": "liu21st",
8 | "email": "liu21st@gmail.com"
9 | }
10 | ],
11 | "require": {
12 | "workerman/workerman":"^3.3.0"
13 | },
14 | "autoload": {
15 | "psr-4": {
16 | "think\\worker\\": "src"
17 | },
18 | "files": [
19 | ]
20 | }
21 | }
--------------------------------------------------------------------------------
/vendor/composer/autoload_psr4.php:
--------------------------------------------------------------------------------
1 | array($vendorDir . '/topthink/think-worker/src'),
10 | 'think\\composer\\' => array($vendorDir . '/topthink/think-installer/src'),
11 | 'think\\' => array($baseDir . '/thinkphp/library/think'),
12 | 'Workerman\\' => array($vendorDir . '/workerman/workerman-for-win', $vendorDir . '/workerman/workerman'),
13 | );
14 |
--------------------------------------------------------------------------------
/application/index/view/index/connect.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 |
20 |
21 |
--------------------------------------------------------------------------------
/config/common.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 |
12 | // 应用公共文件
13 |
--------------------------------------------------------------------------------
/config/command.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 |
12 | return [];
--------------------------------------------------------------------------------
/vendor/topthink/think-installer/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "topthink/think-installer",
3 | "type": "composer-plugin",
4 | "require": {
5 | "composer-plugin-api": "^1.0"
6 | },
7 | "require-dev": {
8 | "composer/composer": "1.0.*@dev"
9 | },
10 | "license": "Apache-2.0",
11 | "authors": [
12 | {
13 | "name": "yunwuxin",
14 | "email": "448901948@qq.com"
15 | }
16 | ],
17 | "autoload": {
18 | "psr-4": {
19 | "think\\composer\\": "src"
20 | }
21 | },
22 | "extra": {
23 | "class": "think\\composer\\Plugin"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/vendor/topthink/think-installer/src/Plugin.php:
--------------------------------------------------------------------------------
1 | getInstallationManager();
15 |
16 | //框架核心
17 | $manager->addInstaller(new ThinkFramework($io, $composer));
18 |
19 | //单元测试
20 | $manager->addInstaller(new ThinkTesting($io, $composer));
21 |
22 | //扩展
23 | $manager->addInstaller(new ThinkExtend($io, $composer));
24 |
25 | }
26 | }
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "topthink/think",
3 | "description": "the new thinkphp framework",
4 | "type": "project",
5 | "keywords": [
6 | "framework",
7 | "thinkphp",
8 | "ORM"
9 | ],
10 | "homepage": "http://thinkphp.cn/",
11 | "license": "Apache-2.0",
12 | "authors": [
13 | {
14 | "name": "liu21st",
15 | "email": "liu21st@gmail.com"
16 | }
17 | ],
18 | "require": {
19 | "php": ">=5.4.0",
20 | "topthink/framework": "^5.0",
21 | "workerman/workerman-for-win": "^3.3",
22 | "topthink/think-worker": "^1.0"
23 | },
24 | "extra": {
25 | "think-path": "thinkphp"
26 | },
27 | "config": {
28 | "preferred-install": "dist"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/public/router.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | // $Id$
12 |
13 | if (is_file($_SERVER["DOCUMENT_ROOT"] . $_SERVER["REQUEST_URI"])) {
14 | return false;
15 | } else {
16 | require __DIR__ . "/index.php";
17 | }
18 |
--------------------------------------------------------------------------------
/think:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 |
11 | // +----------------------------------------------------------------------
12 |
13 | // 定义项目路径
14 | define('APP_PATH', __DIR__ . '/application/');
15 | define('CONF_PATH', __DIR__.'/config/');
16 | // 加载框架引导文件
17 | require './thinkphp/console.php';
--------------------------------------------------------------------------------
/vendor/workerman/workerman-for-win/README.md:
--------------------------------------------------------------------------------
1 | # workerman-for-win
2 | workerman-for-win
3 |
4 | ## 环境要求
5 | (php>=5.3.3)
6 |
7 | ## 运行
8 | 运行一个文件
9 | php your_file.php
10 |
11 | 同时运行多个文件
12 | php your_file.php your_file2.php ...
13 |
14 | ## 与Linux多进程版本的区别
15 | 1、单进程,也就是说count属性无效
16 | 2、由于php在win下无法fork进程,Applications/YourApp/start.php被拆成多个子启动项,如start_web.php start_gateway.php等,每个文件自动启动一个进程运行
17 | 3、由于php在win下不支持信号,所以无法使用reload、status、restart、stop命令,也没有start命令
18 |
19 | ## 手册
20 | 开发与Linux版本基本无差别,可以直接参考Linux版本手册
21 | http://doc3.workerman.net/
22 |
23 | ## 说明
24 | 此版本可用于windows下开发使用,不建议用在生产环境
25 |
26 | ## 移植
27 | ### windows到Linux(需要Linux的Workerman版本3.1.0及以上)
28 | 可以直接将Applications下的应用目录拷贝到Linux版本的Applications下直接运行
29 |
30 | ### Linux到windows
31 | Linux下的应用需要将Applications/YourApp/start.php拆成多个启动项
32 |
33 |
--------------------------------------------------------------------------------
/public/index.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 |
12 | // [ 应用入口文件 ]
13 |
14 | // 定义应用目录
15 | define('APP_PATH', __DIR__ . '/../application/');
16 | define('CONF_PATH', __DIR__.'/config/');
17 | // 加载框架引导文件
18 | require __DIR__ . '/../thinkphp/start.php';
19 |
--------------------------------------------------------------------------------
/config/route.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 |
12 | return [
13 | '__pattern__' => [
14 | 'name' => '\w+',
15 | ],
16 | '[hello]' => [
17 | ':id' => ['index/hello', ['method' => 'get'], ['id' => '\d+']],
18 | ':name' => ['index/hello', ['method' => 'post']],
19 | ],
20 |
21 | ];
22 |
--------------------------------------------------------------------------------
/application/push/controller/Push.php:
--------------------------------------------------------------------------------
1 | close();
22 | }
23 | /**
24 | * 接受推送
25 | * @param $connection
26 | * @param $strData
27 | */
28 | public function toUser($connection, $strData)
29 | {
30 | if( isset(User::$uidList[$strData['toUser']]) ){
31 | User::sendUser(User::$uidList[$strData['toUser']], $strData['sms']);
32 | $connection->send( json_encode(array('errCode'=>0,'errData'=>'OK','data'=>'OK')) );
33 | }else{
34 | $connection->send( json_encode(array('errCode'=>4004,'errData'=>'没有用户映射','data'=>'')) );
35 | }
36 | }
37 |
38 | }
--------------------------------------------------------------------------------
/config/tags.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 |
12 | // 应用行为扩展定义文件
13 | return [
14 | // 应用初始化
15 | 'app_init' => [],
16 | // 应用开始
17 | 'app_begin' => [],
18 | // 模块初始化
19 | 'module_init' => [],
20 | // 操作开始执行
21 | 'action_begin' => [],
22 | // 视图内容过滤
23 | 'view_filter' => [],
24 | // 日志写入
25 | 'log_write' => [],
26 | // 应用结束
27 | 'app_end' => [],
28 | ];
29 |
--------------------------------------------------------------------------------
/vendor/topthink/think-worker/README.md:
--------------------------------------------------------------------------------
1 | ThinkPHP 5.0 Workerman 扩展
2 | ===============
3 |
4 | ## 安装
5 | composer require topthink/think-worker
6 |
7 | ## 使用方法
8 | 首先创建控制器类并继承 think\worker\Server,然后设置属性和添加回调方法
9 |
10 | ~~~
11 | namespace app\index\controller;
12 |
13 | use think\worker\Server;
14 |
15 | class Worker extends Server
16 | {
17 | protected $socket = 'http://0.0.0.0:2346';
18 |
19 | public function onMessage($connection,$data)
20 | {
21 | $connection->send(json_encode($data));
22 | }
23 | }
24 | ~~~
25 | 支持workerman所有的回调方法定义(回调方法必须是public类型)
26 |
27 |
28 | 在应用根目录增加入口文件 server.php
29 |
30 | ~~~
31 | #!/usr/bin/env php
32 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 |
15 | // Date.timezone
16 | if (!ini_get('date.timezone')) {
17 | date_default_timezone_set('Asia/Shanghai');
18 | }
19 | // Display errors.
20 | ini_set('display_errors', 'on');
21 | // Reporting all.
22 | error_reporting(E_ALL);
23 |
24 | // For onError callback.
25 | define('WORKERMAN_CONNECT_FAIL', 1);
26 | // For onError callback.
27 | define('WORKERMAN_SEND_FAIL', 2);
28 |
29 | // Compatible with php7
30 | if(!class_exists('Error'))
31 | {
32 | class Error extends Exception
33 | {
34 | }
35 | }
--------------------------------------------------------------------------------
/vendor/workerman/workerman-for-win/Lib/Constants.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 |
15 | // Date.timezone
16 | if (!ini_get('date.timezone')) {
17 | date_default_timezone_set('Asia/Shanghai');
18 | }
19 | // Display errors.
20 | ini_set('display_errors', 'on');
21 | // Reporting all.
22 | error_reporting(E_ALL);
23 |
24 | // For onError callback.
25 | define('WORKERMAN_CONNECT_FAIL', 1);
26 | // For onError callback.
27 | define('WORKERMAN_SEND_FAIL', 2);
28 |
29 | // Compatible with php7
30 | if(!class_exists('Error'))
31 | {
32 | class Error extends Exception
33 | {
34 | }
35 | }
--------------------------------------------------------------------------------
/application/index/controller/Index.php:
--------------------------------------------------------------------------------
1 | ".json_encode(
10 | array(
11 | 'action' => 'User/bind',
12 | 'data' => array(
13 | 'user' => '123',
14 | )
15 | ),
16 | JSON_UNESCAPED_UNICODE
17 | );
18 | echo "
发送推送:
".json_encode(
19 | array(
20 | 'action' => 'Push/toUser',
21 | 'data' => array(
22 | 'toUser' => '123',
23 | 'sms' => '字符串格式',
24 | ),
25 | 'appid' => '应用id',
26 | 'noncestr' => '随机',
27 | 'timestamp' => time(),
28 | 'signature'=>'签名,',
29 | ),
30 | JSON_UNESCAPED_UNICODE
31 | );
32 | }
33 | public function connect()
34 | {
35 | return view();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman-for-win/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "workerman/workerman-for-win",
3 | "type" : "project",
4 | "keywords": ["event-loop", "asynchronous"],
5 | "homepage": "http://www.workerman.net",
6 | "license" : "MIT",
7 | "description": "An asynchronous event driven PHP framework for easily building fast, scalable network applications.",
8 | "authors" : [
9 | {
10 | "name" : "walkor",
11 | "email" : "walkor@workerman.net",
12 | "homepage" : "http://www.workerman.net",
13 | "role": "Developer"
14 | }
15 | ],
16 | "support" : {
17 | "email" : "walkor@workerman.net",
18 | "issues": "https://github.com/walkor/workerman/issues",
19 | "forum" : "http://wenda.workerman.net/",
20 | "wiki" : "http://doc3.workerman.net/index.html",
21 | "source": "https://github.com/walkor/workerman"
22 | },
23 | "require": {
24 | "php": ">=5.3"
25 | },
26 | "autoload": {
27 | "psr-4": {"Workerman\\": "./"}
28 | },
29 | "minimum-stability":"dev"
30 | }
31 |
--------------------------------------------------------------------------------
/vendor/composer/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Copyright (c) 2016 Nils Adermann, Jordi Boggiano
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy
5 | of this software and associated documentation files (the "Software"), to deal
6 | in the Software without restriction, including without limitation the rights
7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the Software is furnished
9 | to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all
12 | copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | THE SOFTWARE.
21 |
22 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "workerman/workerman",
3 | "type" : "project",
4 | "keywords": ["event-loop", "asynchronous"],
5 | "homepage": "http://www.workerman.net",
6 | "license" : "MIT",
7 | "description": "An asynchronous event driven PHP framework for easily building fast, scalable network applications.",
8 | "authors" : [
9 | {
10 | "name" : "walkor",
11 | "email" : "walkor@workerman.net",
12 | "homepage" : "http://www.workerman.net",
13 | "role": "Developer"
14 | }
15 | ],
16 | "support" : {
17 | "email" : "walkor@workerman.net",
18 | "issues": "https://github.com/walkor/workerman/issues",
19 | "forum" : "http://wenda.workerman.net/",
20 | "wiki" : "http://doc3.workerman.net/index.html",
21 | "source": "https://github.com/walkor/workerman"
22 | },
23 | "require": {
24 | "php": ">=5.3"
25 | },
26 | "suggest": {
27 | "ext-libevent": "For better performance."
28 | },
29 | "autoload": {
30 | "psr-4": {"Workerman\\": "./"}
31 | },
32 | "minimum-stability":"dev"
33 | }
34 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman/MIT-LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2009-2015 walkor and contributors (see https://github.com/walkor/workerman/contributors)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman-for-win/MIT-LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2009-2015 walkor and contributors (see https://github.com/walkor/workerman/contributors)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/vendor/composer/autoload_static.php:
--------------------------------------------------------------------------------
1 |
11 | array (
12 | 'think\\worker\\' => 13,
13 | 'think\\composer\\' => 15,
14 | 'think\\' => 6,
15 | ),
16 | 'W' =>
17 | array (
18 | 'Workerman\\' => 10,
19 | ),
20 | );
21 |
22 | public static $prefixDirsPsr4 = array (
23 | 'think\\worker\\' =>
24 | array (
25 | 0 => __DIR__ . '/..' . '/topthink/think-worker/src',
26 | ),
27 | 'think\\composer\\' =>
28 | array (
29 | 0 => __DIR__ . '/..' . '/topthink/think-installer/src',
30 | ),
31 | 'think\\' =>
32 | array (
33 | 0 => __DIR__ . '/../..' . '/thinkphp/library/think',
34 | ),
35 | 'Workerman\\' =>
36 | array (
37 | 0 => __DIR__ . '/..' . '/workerman/workerman-for-win',
38 | 1 => __DIR__ . '/..' . '/workerman/workerman',
39 | ),
40 | );
41 |
42 | public static function getInitializer(ClassLoader $loader)
43 | {
44 | return \Closure::bind(function () use ($loader) {
45 | $loader->prefixLengthsPsr4 = ComposerStaticInit56313defd83f28b1545e500b0456f8b3::$prefixLengthsPsr4;
46 | $loader->prefixDirsPsr4 = ComposerStaticInit56313defd83f28b1545e500b0456f8b3::$prefixDirsPsr4;
47 |
48 | }, null, ClassLoader::class);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman/Protocols/Frame.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Protocols;
15 |
16 | use Workerman\Connection\TcpConnection;
17 |
18 | /**
19 | * Frame Protocol.
20 | */
21 | class Frame
22 | {
23 | /**
24 | * Check the integrity of the package.
25 | *
26 | * @param string $buffer
27 | * @param TcpConnection $connection
28 | * @return int
29 | */
30 | public static function input($buffer, TcpConnection $connection)
31 | {
32 | if (strlen($buffer) < 4) {
33 | return 0;
34 | }
35 | $unpack_data = unpack('Ntotal_length', $buffer);
36 | return $unpack_data['total_length'];
37 | }
38 |
39 | /**
40 | * Decode.
41 | *
42 | * @param string $buffer
43 | * @return string
44 | */
45 | public static function decode($buffer)
46 | {
47 | return substr($buffer, 4);
48 | }
49 |
50 | /**
51 | * Encode.
52 | *
53 | * @param string $buffer
54 | * @return string
55 | */
56 | public static function encode($buffer)
57 | {
58 | $total_length = 4 + strlen($buffer);
59 | return pack('N', $total_length) . $buffer;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman-for-win/Protocols/Frame.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Protocols;
15 |
16 | use Workerman\Connection\TcpConnection;
17 |
18 | /**
19 | * Frame Protocol.
20 | */
21 | class Frame
22 | {
23 | /**
24 | * Check the integrity of the package.
25 | *
26 | * @param string $buffer
27 | * @param TcpConnection $connection
28 | * @return int
29 | */
30 | public static function input($buffer, TcpConnection $connection)
31 | {
32 | if (strlen($buffer) < 4) {
33 | return 0;
34 | }
35 | $unpack_data = unpack('Ntotal_length', $buffer);
36 | return $unpack_data['total_length'];
37 | }
38 |
39 | /**
40 | * Encode.
41 | *
42 | * @param string $buffer
43 | * @return string
44 | */
45 | public static function decode($buffer)
46 | {
47 | return substr($buffer, 4);
48 | }
49 |
50 | /**
51 | * Decode.
52 | *
53 | * @param string $buffer
54 | * @return string
55 | */
56 | public static function encode($buffer)
57 | {
58 | $total_length = 4 + strlen($buffer);
59 | return pack('N', $total_length) . $buffer;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/application/push/controller/User.php:
--------------------------------------------------------------------------------
1 | close();
25 | }
26 |
27 | public static $uidList = array();
28 | /**
29 | * 新增用户映射
30 | * @param $connection
31 | * @param $strData
32 | */
33 | public function bind($connection,$strData)
34 | {
35 | if( $strData['user'] ){
36 | Timer::del($connection->auth_timer_id);// 验证成功,删除定时器,防止连接被关闭
37 | $connection->user = $strData['user'];
38 | self::$uidList[ $connection->user ] = $connection;
39 | $connection->send( json_encode(array('errCode'=>0,'errData'=>'OK','data'=>'OK')) );
40 | }else{
41 | $connection->send( json_encode(array('errCode'=>4004,'errData'=>'user 参数缺失','data'=>'')) );
42 | }
43 | }
44 |
45 | /**
46 | * 向uid发送信息
47 | * @param $connection
48 | * @param $strData
49 | */
50 | public static function sendUser($connection,$strData)
51 | {
52 | $connection->send( $strData );
53 | }
54 |
55 | /**
56 | * 删除映射
57 | * @param $connection
58 | */
59 | public static function delete($connection)
60 | {
61 | if( isset($connection->user) && isset(self::$uidList[$connection->user]) ){
62 | unset(self::$uidList[$connection->user]);
63 | }
64 | }
65 | }
--------------------------------------------------------------------------------
/config/database.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 |
12 | return [
13 | // 数据库类型
14 | 'type' => 'mysql',
15 | // 服务器地址
16 | 'hostname' => '127.0.0.1',
17 | // 数据库名
18 | 'database' => '',
19 | // 用户名
20 | 'username' => 'root',
21 | // 密码
22 | 'password' => '',
23 | // 端口
24 | 'hostport' => '',
25 | // 连接dsn
26 | 'dsn' => '',
27 | // 数据库连接参数
28 | 'params' => [],
29 | // 数据库编码默认采用utf8
30 | 'charset' => 'utf8',
31 | // 数据库表前缀
32 | 'prefix' => '',
33 | // 数据库调试模式
34 | 'debug' => true,
35 | // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
36 | 'deploy' => 0,
37 | // 数据库读写是否分离 主从式有效
38 | 'rw_separate' => false,
39 | // 读写分离后 主服务器数量
40 | 'master_num' => 1,
41 | // 指定从服务器序号
42 | 'slave_no' => '',
43 | // 是否严格检查字段是否存在
44 | 'fields_strict' => true,
45 | // 数据集返回类型 array 数组 collection Collection对象
46 | 'resultset_type' => 'array',
47 | // 是否自动写入时间戳字段
48 | 'auto_timestamp' => false,
49 | // 是否需要进行SQL性能分析
50 | 'sql_explain' => false,
51 | ];
52 |
--------------------------------------------------------------------------------
/vendor/topthink/think-worker/src/Server.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 |
12 | namespace think\worker;
13 |
14 | use Workerman\Worker;
15 |
16 | /**
17 | * Worker控制器扩展类
18 | */
19 | abstract class Server
20 | {
21 | protected $worker;
22 | protected $socket = '';
23 | protected $protocol = 'http';
24 | protected $host = '0.0.0.0';
25 | protected $port = '2346';
26 | protected $processes = 4;
27 |
28 | /**
29 | * 架构函数
30 | * @access public
31 | */
32 | public function __construct()
33 | {
34 | // 实例化 Websocket 服务
35 | $this->worker = new Worker($this->socket ?: $this->protocol . '://' . $this->host . ':' . $this->port);
36 | // 设置进程数
37 | $this->worker->count = $this->processes;
38 | // 初始化
39 | $this->init();
40 |
41 | // 设置回调
42 | foreach (['onWorkerStart', 'onConnect', 'onMessage', 'onClose', 'onError', 'onBufferFull', 'onBufferDrain', 'onWorkerStop', 'onWorkerReload'] as $event) {
43 | if (method_exists($this, $event)) {
44 | $this->worker->$event = [$this, $event];
45 | }
46 | }
47 | // Run worker
48 | Worker::runAll();
49 | }
50 |
51 | protected function init()
52 | {
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman/Protocols/ProtocolInterface.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Protocols;
15 |
16 | use Workerman\Connection\ConnectionInterface;
17 |
18 | /**
19 | * Protocol interface
20 | */
21 | interface ProtocolInterface
22 | {
23 | /**
24 | * Check the integrity of the package.
25 | * Please return the length of package.
26 | * If length is unknow please return 0 that mean wating more data.
27 | * If the package has something wrong please return false the connection will be closed.
28 | *
29 | * @param ConnectionInterface $connection
30 | * @param string $recv_buffer
31 | * @return int|false
32 | */
33 | public static function input($recv_buffer, ConnectionInterface $connection);
34 |
35 | /**
36 | * Decode package and emit onMessage($message) callback, $message is the result that decode returned.
37 | *
38 | * @param ConnectionInterface $connection
39 | * @param string $recv_buffer
40 | * @return mixed
41 | */
42 | public static function decode($recv_buffer, ConnectionInterface $connection);
43 |
44 | /**
45 | * Encode package brefore sending to client.
46 | *
47 | * @param ConnectionInterface $connection
48 | * @param mixed $data
49 | * @return string
50 | */
51 | public static function encode($data, ConnectionInterface $connection);
52 | }
53 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman-for-win/Protocols/ProtocolInterface.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Protocols;
15 |
16 | use Workerman\Connection\ConnectionInterface;
17 |
18 | /**
19 | * Protocol interface
20 | */
21 | interface ProtocolInterface
22 | {
23 | /**
24 | * Check the integrity of the package.
25 | * Please return the length of package.
26 | * If length is unknow please return 0 that mean wating more data.
27 | * If the package has something wrong please return false the connection will be closed.
28 | *
29 | * @param ConnectionInterface $connection
30 | * @param string $recv_buffer
31 | * @return int|false
32 | */
33 | public static function input($recv_buffer, ConnectionInterface $connection);
34 |
35 | /**
36 | * Decode package and emit onMessage($message) callback, $message is the result that decode returned.
37 | *
38 | * @param ConnectionInterface $connection
39 | * @param string $recv_buffer
40 | * @return mixed
41 | */
42 | public static function decode($recv_buffer, ConnectionInterface $connection);
43 |
44 | /**
45 | * Encode package brefore sending to client.
46 | *
47 | * @param ConnectionInterface $connection
48 | * @param mixed $data
49 | * @return string
50 | */
51 | public static function encode($data, ConnectionInterface $connection);
52 | }
53 |
--------------------------------------------------------------------------------
/vendor/composer/autoload_real.php:
--------------------------------------------------------------------------------
1 | = 50600 && !defined('HHVM_VERSION');
27 | if ($useStaticLoader) {
28 | require_once __DIR__ . '/autoload_static.php';
29 |
30 | call_user_func(\Composer\Autoload\ComposerStaticInit56313defd83f28b1545e500b0456f8b3::getInitializer($loader));
31 | } else {
32 | $map = require __DIR__ . '/autoload_namespaces.php';
33 | foreach ($map as $namespace => $path) {
34 | $loader->set($namespace, $path);
35 | }
36 |
37 | $map = require __DIR__ . '/autoload_psr4.php';
38 | foreach ($map as $namespace => $path) {
39 | $loader->setPsr4($namespace, $path);
40 | }
41 |
42 | $classMap = require __DIR__ . '/autoload_classmap.php';
43 | if ($classMap) {
44 | $loader->addClassMap($classMap);
45 | }
46 | }
47 |
48 | $loader->register(true);
49 |
50 | return $loader;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman/Events/EventInterface.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Events;
15 |
16 | interface EventInterface
17 | {
18 | /**
19 | * Read event.
20 | *
21 | * @var int
22 | */
23 | const EV_READ = 1;
24 |
25 | /**
26 | * Write event.
27 | *
28 | * @var int
29 | */
30 | const EV_WRITE = 2;
31 |
32 | /**
33 | * Signal event.
34 | *
35 | * @var int
36 | */
37 | const EV_SIGNAL = 4;
38 |
39 | /**
40 | * Timer event.
41 | *
42 | * @var int
43 | */
44 | const EV_TIMER = 8;
45 |
46 | /**
47 | * Timer once event.
48 | *
49 | * @var int
50 | */
51 | const EV_TIMER_ONCE = 16;
52 |
53 | /**
54 | * Add event listener to event loop.
55 | *
56 | * @param mixed $fd
57 | * @param int $flag
58 | * @param callable $func
59 | * @param mixed $args
60 | * @return bool
61 | */
62 | public function add($fd, $flag, $func, $args = null);
63 |
64 | /**
65 | * Remove event listener from event loop.
66 | *
67 | * @param mixed $fd
68 | * @param int $flag
69 | * @return bool
70 | */
71 | public function del($fd, $flag);
72 |
73 | /**
74 | * Remove all timers.
75 | *
76 | * @return void
77 | */
78 | public function clearAllTimer();
79 |
80 | /**
81 | * Main loop.
82 | *
83 | * @return void
84 | */
85 | public function loop();
86 | }
87 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman/Protocols/Text.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Protocols;
15 |
16 | use Workerman\Connection\TcpConnection;
17 |
18 | /**
19 | * Text Protocol.
20 | */
21 | class Text
22 | {
23 | /**
24 | * Check the integrity of the package.
25 | *
26 | * @param string $buffer
27 | * @param TcpConnection $connection
28 | * @return int
29 | */
30 | public static function input($buffer, TcpConnection $connection)
31 | {
32 | // Judge whether the package length exceeds the limit.
33 | if (strlen($buffer) >= TcpConnection::$maxPackageSize) {
34 | $connection->close();
35 | return 0;
36 | }
37 | // Find the position of "\n".
38 | $pos = strpos($buffer, "\n");
39 | // No "\n", packet length is unknown, continue to wait for the data so return 0.
40 | if ($pos === false) {
41 | return 0;
42 | }
43 | // Return the current package length.
44 | return $pos + 1;
45 | }
46 |
47 | /**
48 | * Encode.
49 | *
50 | * @param string $buffer
51 | * @return string
52 | */
53 | public static function encode($buffer)
54 | {
55 | // Add "\n"
56 | return $buffer . "\n";
57 | }
58 |
59 | /**
60 | * Decode.
61 | *
62 | * @param string $buffer
63 | * @return string
64 | */
65 | public static function decode($buffer)
66 | {
67 | // Remove "\n"
68 | return trim($buffer);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman-for-win/Protocols/Text.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Protocols;
15 |
16 | use Workerman\Connection\TcpConnection;
17 |
18 | /**
19 | * Text Protocol.
20 | */
21 | class Text
22 | {
23 | /**
24 | * Check the integrity of the package.
25 | *
26 | * @param string $buffer
27 | * @param TcpConnection $connection
28 | * @return int
29 | */
30 | public static function input($buffer, TcpConnection $connection)
31 | {
32 | // Judge whether the package length exceeds the limit.
33 | if (strlen($buffer) >= TcpConnection::$maxPackageSize) {
34 | $connection->close();
35 | return 0;
36 | }
37 | // Find the position of "\n".
38 | $pos = strpos($buffer, "\n");
39 | // No "\n", packet length is unknown, continue to wait for the data so return 0.
40 | if ($pos === false) {
41 | return 0;
42 | }
43 | // Return the current package length.
44 | return $pos + 1;
45 | }
46 |
47 | /**
48 | * Encode.
49 | *
50 | * @param string $buffer
51 | * @return string
52 | */
53 | public static function encode($buffer)
54 | {
55 | // Add "\n"
56 | return $buffer . "\n";
57 | }
58 |
59 | /**
60 | * Decode.
61 | *
62 | * @param string $buffer
63 | * @return string
64 | */
65 | public static function decode($buffer)
66 | {
67 | // Remove "\n"
68 | return trim($buffer);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/vendor/topthink/think-installer/src/ThinkFramework.php:
--------------------------------------------------------------------------------
1 | getPrettyName()) {
17 | throw new \InvalidArgumentException('Unable to install this library!');
18 | }
19 |
20 | if ($this->composer->getPackage()->getType() !== 'project') {
21 | return parent::getInstallPath($package);
22 | }
23 |
24 | if ($this->composer->getPackage()) {
25 | $extra = $this->composer->getPackage()->getExtra();
26 | if (!empty($extra['think-path'])) {
27 | return $extra['think-path'];
28 | }
29 | }
30 |
31 | return 'thinkphp';
32 | }
33 |
34 | public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
35 | {
36 | parent::install($repo, $package);
37 | if ($this->composer->getPackage()->getType() == 'project') {
38 | //remove tests dir
39 | $this->filesystem->removeDirectory($this->getInstallPath($package) . DIRECTORY_SEPARATOR . 'tests');
40 | }
41 | }
42 |
43 | public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
44 | {
45 | parent::update($repo, $initial, $target);
46 | if ($this->composer->getPackage()->getType() == 'project') {
47 | //remove tests dir
48 | $this->filesystem->removeDirectory($this->getInstallPath($target) . DIRECTORY_SEPARATOR . 'tests');
49 | }
50 | }
51 |
52 | /**
53 | * {@inheritDoc}
54 | */
55 | public function supports($packageType)
56 | {
57 | return 'think-framework' === $packageType;
58 | }
59 | }
--------------------------------------------------------------------------------
/vendor/workerman/workerman-for-win/Events/EventInterface.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Events;
15 |
16 | interface EventInterface
17 | {
18 | /**
19 | * Read event.
20 | *
21 | * @var int
22 | */
23 | const EV_READ = 1;
24 |
25 | /**
26 | * Write event.
27 | *
28 | * @var int
29 | */
30 | const EV_WRITE = 2;
31 |
32 | /**
33 | * Except event
34 | *
35 | * @var int
36 | */
37 | const EV_EXCEPT = 3;
38 |
39 | /**
40 | * Signal event.
41 | *
42 | * @var int
43 | */
44 | const EV_SIGNAL = 4;
45 |
46 | /**
47 | * Timer event.
48 | *
49 | * @var int
50 | */
51 | const EV_TIMER = 8;
52 |
53 | /**
54 | * Timer once event.
55 | *
56 | * @var int
57 | */
58 | const EV_TIMER_ONCE = 16;
59 |
60 | /**
61 | * Add event listener to event loop.
62 | *
63 | * @param mixed $fd
64 | * @param int $flag
65 | * @param callable $func
66 | * @param mixed $args
67 | * @return bool
68 | */
69 | public function add($fd, $flag, $func, $args = null);
70 |
71 | /**
72 | * Remove event listener from event loop.
73 | *
74 | * @param mixed $fd
75 | * @param int $flag
76 | * @return bool
77 | */
78 | public function del($fd, $flag);
79 |
80 | /**
81 | * Remove all timers.
82 | *
83 | * @return void
84 | */
85 | public function clearAllTimer();
86 |
87 | /**
88 | * Main loop.
89 | *
90 | * @return void
91 | */
92 | public function loop();
93 | }
94 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman/Connection/ConnectionInterface.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Connection;
15 |
16 | /**
17 | * ConnectionInterface.
18 | */
19 | abstract class ConnectionInterface
20 | {
21 | /**
22 | * Statistics for status command.
23 | *
24 | * @var array
25 | */
26 | public static $statistics = array(
27 | 'connection_count' => 0,
28 | 'total_request' => 0,
29 | 'throw_exception' => 0,
30 | 'send_fail' => 0,
31 | );
32 |
33 | /**
34 | * Emitted when data is received.
35 | *
36 | * @var callback
37 | */
38 | public $onMessage = null;
39 |
40 | /**
41 | * Emitted when the other end of the socket sends a FIN packet.
42 | *
43 | * @var callback
44 | */
45 | public $onClose = null;
46 |
47 | /**
48 | * Emitted when an error occurs with connection.
49 | *
50 | * @var callback
51 | */
52 | public $onError = null;
53 |
54 | /**
55 | * Sends data on the connection.
56 | *
57 | * @param string $send_buffer
58 | * @return void|boolean
59 | */
60 | abstract public function send($send_buffer);
61 |
62 | /**
63 | * Get remote IP.
64 | *
65 | * @return string
66 | */
67 | abstract public function getRemoteIp();
68 |
69 | /**
70 | * Get remote port.
71 | *
72 | * @return int
73 | */
74 | abstract public function getRemotePort();
75 |
76 | /**
77 | * Close connection.
78 | *
79 | * @param $data
80 | * @return void
81 | */
82 | abstract public function close($data = null);
83 | }
84 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman-for-win/Connection/ConnectionInterface.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Connection;
15 |
16 | /**
17 | * ConnectionInterface.
18 | */
19 | abstract class ConnectionInterface
20 | {
21 | /**
22 | * Statistics for status command.
23 | *
24 | * @var array
25 | */
26 | public static $statistics = array(
27 | 'connection_count' => 0,
28 | 'total_request' => 0,
29 | 'throw_exception' => 0,
30 | 'send_fail' => 0,
31 | );
32 |
33 | /**
34 | * Emitted when data is received.
35 | *
36 | * @var callback
37 | */
38 | public $onMessage = null;
39 |
40 | /**
41 | * Emitted when the other end of the socket sends a FIN packet.
42 | *
43 | * @var callback
44 | */
45 | public $onClose = null;
46 |
47 | /**
48 | * Emitted when an error occurs with connection.
49 | *
50 | * @var callback
51 | */
52 | public $onError = null;
53 |
54 | /**
55 | * Sends data on the connection.
56 | *
57 | * @param string $send_buffer
58 | * @return void|boolean
59 | */
60 | abstract public function send($send_buffer);
61 |
62 | /**
63 | * Get remote IP.
64 | *
65 | * @return string
66 | */
67 | abstract public function getRemoteIp();
68 |
69 | /**
70 | * Get remote port.
71 | *
72 | * @return int
73 | */
74 | abstract public function getRemotePort();
75 |
76 | /**
77 | * Close connection.
78 | *
79 | * @param $data
80 | * @return void
81 | */
82 | abstract public function close($data = null);
83 | }
84 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman/Autoloader.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman;
15 |
16 | /**
17 | * Autoload.
18 | */
19 | class Autoloader
20 | {
21 | /**
22 | * Autoload root path.
23 | *
24 | * @var string
25 | */
26 | protected static $_autoloadRootPath = '';
27 |
28 | /**
29 | * Set autoload root path.
30 | *
31 | * @param string $root_path
32 | * @return void
33 | */
34 | public static function setRootPath($root_path)
35 | {
36 | self::$_autoloadRootPath = $root_path;
37 | }
38 |
39 | /**
40 | * Load files by namespace.
41 | *
42 | * @param string $name
43 | * @return boolean
44 | */
45 | public static function loadByNamespace($name)
46 | {
47 | $class_path = str_replace('\\', DIRECTORY_SEPARATOR, $name);
48 | if (strpos($name, 'Workerman\\') === 0) {
49 | $class_file = __DIR__ . substr($class_path, strlen('Workerman')) . '.php';
50 | } else {
51 | if (self::$_autoloadRootPath) {
52 | $class_file = self::$_autoloadRootPath . DIRECTORY_SEPARATOR . $class_path . '.php';
53 | }
54 | if (empty($class_file) || !is_file($class_file)) {
55 | $class_file = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . "$class_path.php";
56 | }
57 | }
58 |
59 | if (is_file($class_file)) {
60 | require_once($class_file);
61 | if (class_exists($name, false)) {
62 | return true;
63 | }
64 | }
65 | return false;
66 | }
67 | }
68 |
69 | spl_autoload_register('\Workerman\Autoloader::loadByNamespace');
--------------------------------------------------------------------------------
/vendor/topthink/think-installer/src/ThinkTesting.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 |
12 | namespace think\composer;
13 |
14 |
15 | use Composer\Installer\LibraryInstaller;
16 | use Composer\Package\PackageInterface;
17 | use Composer\Repository\InstalledRepositoryInterface;
18 |
19 | class ThinkTesting extends LibraryInstaller
20 | {
21 | /**
22 | * {@inheritDoc}
23 | */
24 | public function getInstallPath(PackageInterface $package)
25 | {
26 | if ('topthink/think-testing' !== $package->getPrettyName()) {
27 | throw new \InvalidArgumentException('Unable to install this library!');
28 | }
29 |
30 | return parent::getInstallPath($package);
31 | }
32 |
33 | public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
34 | {
35 | parent::install($repo, $package);
36 |
37 | $this->copyTestDir($package);
38 |
39 |
40 | }
41 |
42 | public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
43 | {
44 | parent::update($repo, $initial, $target);
45 |
46 | $this->copyTestDir($target);
47 |
48 | }
49 |
50 | private function copyTestDir(PackageInterface $package)
51 | {
52 | $appDir = dirname($this->vendorDir);
53 | $source = $this->getInstallPath($package) . DIRECTORY_SEPARATOR . 'example';
54 | if (!is_file($appDir . DIRECTORY_SEPARATOR . 'phpunit.xml')) {
55 | $this->filesystem->copyThenRemove($source, $appDir);
56 | } else {
57 | $this->filesystem->removeDirectoryPhp($source);
58 | }
59 | }
60 |
61 | /**
62 | * {@inheritDoc}
63 | */
64 | public function supports($packageType)
65 | {
66 | return 'think-testing' === $packageType;
67 | }
68 | }
--------------------------------------------------------------------------------
/vendor/workerman/workerman-for-win/Autoloader.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman;
15 |
16 | // 包含常量定义文件
17 | require_once __DIR__.'/Lib/Constants.php';
18 |
19 | /**
20 | * 自动加载类
21 | * @author walkor
22 | */
23 | class Autoloader
24 | {
25 | // 应用的初始化目录,作为加载类文件的参考目录
26 | protected static $_appInitPath = '';
27 |
28 | /**
29 | * 设置应用初始化目录
30 | * @param string $root_path
31 | * @return void
32 | */
33 | public static function setRootPath($root_path)
34 | {
35 | self::$_appInitPath = $root_path;
36 | }
37 |
38 | /**
39 | * 根据命名空间加载文件
40 | * @param string $name
41 | * @return boolean
42 | */
43 | public static function loadByNamespace($name)
44 | {
45 | // 相对路径
46 | $class_path = str_replace('\\', DIRECTORY_SEPARATOR ,$name);
47 | // 如果是Workerman命名空间,则在当前目录寻找类文件
48 | if(strpos($name, 'Workerman\\') === 0)
49 | {
50 | $class_file = __DIR__.substr($class_path, strlen('Workerman')).'.php';
51 | }
52 | else
53 | {
54 | // 先尝试在应用目录寻找文件
55 | if(self::$_appInitPath)
56 | {
57 | $class_file = self::$_appInitPath . DIRECTORY_SEPARATOR . $class_path.'.php';
58 | }
59 | // 文件不存在,则在上一层目录寻找
60 | if(empty($class_file) || !is_file($class_file))
61 | {
62 | $class_file = __DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR . "$class_path.php";
63 | }
64 | }
65 |
66 | // 找到文件
67 | if(is_file($class_file))
68 | {
69 | // 加载
70 | require_once($class_file);
71 | if(class_exists($name, false))
72 | {
73 | return true;
74 | }
75 | }
76 | return false;
77 | }
78 | }
79 | // 设置类自动加载回调函数
80 | spl_autoload_register('\Workerman\Autoloader::loadByNamespace');
--------------------------------------------------------------------------------
/vendor/topthink/think-installer/src/ThinkExtend.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 |
12 | namespace think\composer;
13 |
14 | use Composer\Installer\LibraryInstaller;
15 | use Composer\Package\PackageInterface;
16 | use Composer\Repository\InstalledRepositoryInterface;
17 |
18 | class ThinkExtend extends LibraryInstaller
19 | {
20 |
21 | public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
22 | {
23 | parent::install($repo, $package);
24 | $this->copyExtraFiles($package);
25 | }
26 |
27 | public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
28 | {
29 | parent::update($repo, $initial, $target);
30 | $this->copyExtraFiles($target);
31 |
32 | }
33 |
34 | protected function copyExtraFiles(PackageInterface $package)
35 | {
36 | $extra = $package->getExtra();
37 |
38 | if (!empty($extra['think-config'])) {
39 |
40 | $composerExtra = $this->composer->getPackage()->getExtra();
41 | $extraDir = (!empty($composerExtra['app-path']) ? $composerExtra['app-path'] : 'application') . DIRECTORY_SEPARATOR . 'extra';
42 | $this->filesystem->ensureDirectoryExists($extraDir);
43 |
44 | //配置文件
45 | foreach ((array) $extra['think-config'] as $name => $config) {
46 | $target = $extraDir . DIRECTORY_SEPARATOR . $name . '.php';
47 | $source = $this->getInstallPath($package) . DIRECTORY_SEPARATOR . $config;
48 |
49 | if (is_file($target)) {
50 | $this->io->write("File {$target} exist!");
51 | continue;
52 | }
53 |
54 | if (!is_file($source)) {
55 | $this->io->write("File {$target} not exist!");
56 | continue;
57 | }
58 |
59 | copy($source, $target);
60 | }
61 | }
62 | }
63 |
64 | public function supports($packageType)
65 | {
66 | return 'think-extend' === $packageType;
67 | }
68 | }
--------------------------------------------------------------------------------
/vendor/workerman/workerman-for-win/Connection/UdpConnection.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Connection;
15 |
16 | /**
17 | * UdpConnection.
18 | */
19 | class UdpConnection extends ConnectionInterface
20 | {
21 | /**
22 | * Application layer protocol.
23 | * The format is like this Workerman\\Protocols\\Http.
24 | *
25 | * @var \Workerman\Protocols\ProtocolInterface
26 | */
27 | public $protocol = null;
28 |
29 | /**
30 | * Udp socket.
31 | *
32 | * @var resource
33 | */
34 | protected $_socket = null;
35 |
36 | /**
37 | * Remote address.
38 | *
39 | * @var string
40 | */
41 | protected $_remoteAddress = '';
42 |
43 | /**
44 | * Construct.
45 | *
46 | * @param resource $socket
47 | * @param string $remote_address
48 | */
49 | public function __construct($socket, $remote_address)
50 | {
51 | $this->_socket = $socket;
52 | $this->_remoteAddress = $remote_address;
53 | }
54 |
55 | /**
56 | * Sends data on the connection.
57 | *
58 | * @param string $send_buffer
59 | * @param bool $raw
60 | * @return void|boolean
61 | */
62 | public function send($send_buffer, $raw = false)
63 | {
64 | if (false === $raw && $this->protocol) {
65 | $parser = $this->protocol;
66 | $send_buffer = $parser::encode($send_buffer, $this);
67 | if ($send_buffer === '') {
68 | return null;
69 | }
70 | }
71 | return strlen($send_buffer) === stream_socket_sendto($this->_socket, $send_buffer, 0, $this->_remoteAddress);
72 | }
73 |
74 | /**
75 | * Get remote IP.
76 | *
77 | * @return string
78 | */
79 | public function getRemoteIp()
80 | {
81 | $pos = strrpos($this->_remoteAddress, ':');
82 | if ($pos) {
83 | return trim(substr($this->_remoteAddress, 0, $pos), '[]');
84 | }
85 | return '';
86 | }
87 |
88 | /**
89 | * Get remote port.
90 | *
91 | * @return int
92 | */
93 | public function getRemotePort()
94 | {
95 | if ($this->_remoteAddress) {
96 | return (int)substr(strrchr($this->_remoteAddress, ':'), 1);
97 | }
98 | return 0;
99 | }
100 |
101 | /**
102 | * Close connection.
103 | *
104 | * @param mixed $data
105 | * @return bool
106 | */
107 | public function close($data = null, $raw = false)
108 | {
109 | if ($data !== null) {
110 | $this->send($data, $raw);
111 | }
112 | return true;
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman/Connection/UdpConnection.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Connection;
15 |
16 | /**
17 | * UdpConnection.
18 | */
19 | class UdpConnection extends ConnectionInterface
20 | {
21 | /**
22 | * Application layer protocol.
23 | * The format is like this Workerman\\Protocols\\Http.
24 | *
25 | * @var \Workerman\Protocols\ProtocolInterface
26 | */
27 | public $protocol = null;
28 |
29 | /**
30 | * Udp socket.
31 | *
32 | * @var resource
33 | */
34 | protected $_socket = null;
35 |
36 | /**
37 | * Remote address.
38 | *
39 | * @var string
40 | */
41 | protected $_remoteAddress = '';
42 |
43 | /**
44 | * Construct.
45 | *
46 | * @param resource $socket
47 | * @param string $remote_address
48 | */
49 | public function __construct($socket, $remote_address)
50 | {
51 | $this->_socket = $socket;
52 | $this->_remoteAddress = $remote_address;
53 | }
54 |
55 | /**
56 | * Sends data on the connection.
57 | *
58 | * @param string $send_buffer
59 | * @param bool $raw
60 | * @return void|boolean
61 | */
62 | public function send($send_buffer, $raw = false)
63 | {
64 | if (false === $raw && $this->protocol) {
65 | $parser = $this->protocol;
66 | $send_buffer = $parser::encode($send_buffer, $this);
67 | if ($send_buffer === '') {
68 | return null;
69 | }
70 | }
71 | return strlen($send_buffer) === stream_socket_sendto($this->_socket, $send_buffer, 0, $this->_remoteAddress);
72 | }
73 |
74 | /**
75 | * Get remote IP.
76 | *
77 | * @return string
78 | */
79 | public function getRemoteIp()
80 | {
81 | $pos = strrpos($this->_remoteAddress, ':');
82 | if ($pos) {
83 | return trim(substr($this->_remoteAddress, 0, $pos), '[]');
84 | }
85 | return '';
86 | }
87 |
88 | /**
89 | * Get remote port.
90 | *
91 | * @return int
92 | */
93 | public function getRemotePort()
94 | {
95 | if ($this->_remoteAddress) {
96 | return (int)substr(strrchr($this->_remoteAddress, ':'), 1);
97 | }
98 | return 0;
99 | }
100 |
101 | /**
102 | * Close connection.
103 | *
104 | * @param mixed $data
105 | * @param bool $raw
106 | * @return bool
107 | */
108 | public function close($data = null, $raw = false)
109 | {
110 | if ($data !== null) {
111 | $this->send($data, $raw);
112 | }
113 | return true;
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman-for-win/Connection/AsyncUdpConnection.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Connection;
15 |
16 | use Workerman\Events\EventInterface;
17 | use Workerman\Worker;
18 | use Exception;
19 |
20 | /**
21 | * AsyncTcpConnection.
22 | */
23 | class AsyncUdpConnection extends UdpConnection
24 | {
25 | /**
26 | * Construct.
27 | *
28 | * @param string $remote_address
29 | * @throws Exception
30 | */
31 | public function __construct($remote_address)
32 | {
33 | // Get the application layer communication protocol and listening address.
34 | list($scheme, $address) = explode(':', $remote_address, 2);
35 | // Check application layer protocol class.
36 | if ($scheme !== 'udp') {
37 | $scheme = ucfirst($scheme);
38 | $this->protocol = '\\Protocols\\' . $scheme;
39 | if (!class_exists($this->protocol)) {
40 | $this->protocol = "\\Workerman\\Protocols\\$scheme";
41 | if (!class_exists($this->protocol)) {
42 | throw new Exception("class \\Protocols\\$scheme not exist");
43 | }
44 | }
45 | }
46 |
47 | $this->_remoteAddress = substr($address, 2);
48 | $this->_socket = stream_socket_client("udp://{$this->_remoteAddress}");
49 | Worker::$globalEvent->add($this->_socket, EventInterface::EV_READ, array($this, 'baseRead'));
50 | }
51 |
52 | /**
53 | * For udp package.
54 | *
55 | * @param resource $socket
56 | * @return bool
57 | */
58 | public function baseRead($socket)
59 | {
60 | $recv_buffer = stream_socket_recvfrom($socket, Worker::MAX_UDP_PACKAGE_SIZE, 0, $remote_address);
61 | if (false === $recv_buffer || empty($remote_address)) {
62 | return false;
63 | }
64 |
65 | if ($this->onMessage) {
66 | if ($this->protocol) {
67 | $parser = $this->protocol;
68 | $recv_buffer = $parser::decode($recv_buffer, $this);
69 | }
70 | ConnectionInterface::$statistics['total_request']++;
71 | try {
72 | call_user_func($this->onMessage, $this, $recv_buffer);
73 | } catch (\Exception $e) {
74 | self::log($e);
75 | exit(250);
76 | } catch (\Error $e) {
77 | self::log($e);
78 | exit(250);
79 | }
80 | }
81 | return true;
82 | }
83 |
84 |
85 | /**
86 | * Close connection.
87 | *
88 | * @param mixed $data
89 | * @return bool
90 | */
91 | public function close($data = null, $raw = false)
92 | {
93 | if ($data !== null) {
94 | $this->send($data, $raw);
95 | }
96 | Worker::$globalEvent->del($this->_socket, EventInterface::EV_READ);
97 | fclose($this->_socket);
98 | return true;
99 | }
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/application/push/controller/Worker.php:
--------------------------------------------------------------------------------
1 | socket = Config::get('workerman.socket');
16 | parent::__construct();
17 | }
18 |
19 | /**
20 | * 收到信息
21 | * @param $connection
22 | * @param $data
23 | */
24 | public function onMessage($connection, $data)
25 | {
26 | $arrData = json_decode($data, true);
27 | if (!$arrData['action']) {
28 | $connection->send('action 参数不存在');
29 | } else {
30 | $arrAction = explode('/', $arrData['action']);
31 | $class = 'app\\push\\controller\\' . $arrAction[0];
32 | $func = $arrAction[1];
33 | if (class_exists($class)) {
34 | $obj = new $class($connection,$arrData);
35 | if (method_exists($obj, $func)) {
36 | $obj->$func($connection, $arrData['data']);
37 | } else {
38 | $connection->send($func . '类的方法不存在');
39 | }
40 | } else {
41 | $connection->send($class . '类不存在');
42 | }
43 | }
44 | }
45 |
46 | /**
47 | * 当连接建立时触发的回调函数
48 | * @param $connection
49 | */
50 | public function onConnect($connection)
51 | {
52 | // 临时给$connection对象添加一个auth_timer_id属性存储定时器id
53 | // 定时30秒关闭连接,需要客户端30秒内发送验证删除定时器
54 | $connection->auth_timer_id = Timer::add(30, function()use($connection){
55 | $connection->close();
56 | }, null, false);
57 | }
58 |
59 | /**
60 | * 当连接断开时触发的回调函数
61 | * @param $connection
62 | */
63 | public function onClose($connection)
64 | {
65 | User::delete($connection);
66 | }
67 |
68 | /**
69 | * 当客户端的连接上发生错误时触发
70 | * @param $connection
71 | * @param $code
72 | * @param $msg
73 | */
74 | public function onError($connection, $code, $msg)
75 | {
76 | echo "error $code $msg\n";
77 | }
78 |
79 | /**
80 | * 每个进程启动
81 | * @param $worker
82 | */
83 | public function onWorkerStart($worker)
84 | {
85 | // 开启一个内部端口,方便内部系统推送数据,Text协议格式 文本+换行符
86 | $inner_text_worker = new \Workerman\Worker( Config::get('workerman.text') );
87 | $inner_text_worker->onMessage = function($connection, $data)
88 | {
89 | if( !is_array($data) ){
90 | $arrData = json_decode($data,true);
91 | }
92 | if( is_array($arrData) && !empty($arrData) ){
93 | $arrAction = explode('/', $arrData['action']);
94 | $class = 'app\\push\\controller\\' . $arrAction[0];
95 | $func = $arrAction[1];
96 | if (class_exists($class)) {
97 | $obj = new $class($connection,$arrData);
98 | if (method_exists($obj, $func)) {
99 | $obj->$func($connection, $arrData['data']);
100 | } else {
101 | $connection->send($func . '类的方法不存在');
102 | }
103 | } else {
104 | $connection->send($class . '类不存在');
105 | }
106 | }else{
107 | $connection->send( json_encode(array('errCode'=>5004,'errData'=>'数据格式错误','data'=>'')) );
108 | }
109 | };
110 | $inner_text_worker->listen();
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman/Protocols/Http/mime.types:
--------------------------------------------------------------------------------
1 |
2 | types {
3 | text/html html htm shtml;
4 | text/css css;
5 | text/xml xml;
6 | image/gif gif;
7 | image/jpeg jpeg jpg;
8 | application/x-javascript js;
9 | application/atom+xml atom;
10 | application/rss+xml rss;
11 |
12 | text/mathml mml;
13 | text/plain txt;
14 | text/vnd.sun.j2me.app-descriptor jad;
15 | text/vnd.wap.wml wml;
16 | text/x-component htc;
17 |
18 | image/png png;
19 | image/tiff tif tiff;
20 | image/vnd.wap.wbmp wbmp;
21 | image/x-icon ico;
22 | image/x-jng jng;
23 | image/x-ms-bmp bmp;
24 | image/svg+xml svg svgz;
25 | image/webp webp;
26 |
27 | application/java-archive jar war ear;
28 | application/mac-binhex40 hqx;
29 | application/msword doc;
30 | application/pdf pdf;
31 | application/postscript ps eps ai;
32 | application/rtf rtf;
33 | application/vnd.ms-excel xls;
34 | application/vnd.ms-powerpoint ppt;
35 | application/vnd.wap.wmlc wmlc;
36 | application/vnd.google-earth.kml+xml kml;
37 | application/vnd.google-earth.kmz kmz;
38 | application/x-7z-compressed 7z;
39 | application/x-cocoa cco;
40 | application/x-java-archive-diff jardiff;
41 | application/x-java-jnlp-file jnlp;
42 | application/x-makeself run;
43 | application/x-perl pl pm;
44 | application/x-pilot prc pdb;
45 | application/x-rar-compressed rar;
46 | application/x-redhat-package-manager rpm;
47 | application/x-sea sea;
48 | application/x-shockwave-flash swf;
49 | application/x-stuffit sit;
50 | application/x-tcl tcl tk;
51 | application/x-x509-ca-cert der pem crt;
52 | application/x-xpinstall xpi;
53 | application/xhtml+xml xhtml;
54 | application/zip zip;
55 |
56 | application/octet-stream bin exe dll;
57 | application/octet-stream deb;
58 | application/octet-stream dmg;
59 | application/octet-stream eot;
60 | application/octet-stream iso img;
61 | application/octet-stream msi msp msm;
62 |
63 | audio/midi mid midi kar;
64 | audio/mpeg mp3;
65 | audio/ogg ogg;
66 | audio/x-m4a m4a;
67 | audio/x-realaudio ra;
68 |
69 | video/3gpp 3gpp 3gp;
70 | video/mp4 mp4;
71 | video/mpeg mpeg mpg;
72 | video/quicktime mov;
73 | video/webm webm;
74 | video/x-flv flv;
75 | video/x-m4v m4v;
76 | video/x-mng mng;
77 | video/x-ms-asf asx asf;
78 | video/x-ms-wmv wmv;
79 | video/x-msvideo avi;
80 | }
81 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman-for-win/Protocols/Http/mime.types:
--------------------------------------------------------------------------------
1 |
2 | types {
3 | text/html html htm shtml;
4 | text/css css;
5 | text/xml xml;
6 | image/gif gif;
7 | image/jpeg jpeg jpg;
8 | application/x-javascript js;
9 | application/atom+xml atom;
10 | application/rss+xml rss;
11 |
12 | text/mathml mml;
13 | text/plain txt;
14 | text/vnd.sun.j2me.app-descriptor jad;
15 | text/vnd.wap.wml wml;
16 | text/x-component htc;
17 |
18 | image/png png;
19 | image/tiff tif tiff;
20 | image/vnd.wap.wbmp wbmp;
21 | image/x-icon ico;
22 | image/x-jng jng;
23 | image/x-ms-bmp bmp;
24 | image/svg+xml svg svgz;
25 | image/webp webp;
26 |
27 | application/java-archive jar war ear;
28 | application/mac-binhex40 hqx;
29 | application/msword doc;
30 | application/pdf pdf;
31 | application/postscript ps eps ai;
32 | application/rtf rtf;
33 | application/vnd.ms-excel xls;
34 | application/vnd.ms-powerpoint ppt;
35 | application/vnd.wap.wmlc wmlc;
36 | application/vnd.google-earth.kml+xml kml;
37 | application/vnd.google-earth.kmz kmz;
38 | application/x-7z-compressed 7z;
39 | application/x-cocoa cco;
40 | application/x-java-archive-diff jardiff;
41 | application/x-java-jnlp-file jnlp;
42 | application/x-makeself run;
43 | application/x-perl pl pm;
44 | application/x-pilot prc pdb;
45 | application/x-rar-compressed rar;
46 | application/x-redhat-package-manager rpm;
47 | application/x-sea sea;
48 | application/x-shockwave-flash swf;
49 | application/x-stuffit sit;
50 | application/x-tcl tcl tk;
51 | application/x-x509-ca-cert der pem crt;
52 | application/x-xpinstall xpi;
53 | application/xhtml+xml xhtml;
54 | application/zip zip;
55 |
56 | application/octet-stream bin exe dll;
57 | application/octet-stream deb;
58 | application/octet-stream dmg;
59 | application/octet-stream eot;
60 | application/octet-stream iso img;
61 | application/octet-stream msi msp msm;
62 |
63 | audio/midi mid midi kar;
64 | audio/mpeg mp3;
65 | audio/ogg ogg;
66 | audio/x-m4a m4a;
67 | audio/x-realaudio ra;
68 |
69 | video/3gpp 3gpp 3gp;
70 | video/mp4 mp4;
71 | video/mpeg mpeg mpg;
72 | video/quicktime mov;
73 | video/webm webm;
74 | video/x-flv flv;
75 | video/x-m4v m4v;
76 | video/x-mng mng;
77 | video/x-ms-asf asx asf;
78 | video/x-ms-wmv wmv;
79 | video/x-msvideo avi;
80 | }
81 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ThinkPHP 5.0
2 | ===============
3 |
4 | [](https://packagist.org/packages/topthink/think)
5 | [](https://packagist.org/packages/topthink/think)
6 | [](https://packagist.org/packages/topthink/think)
7 | [](https://packagist.org/packages/topthink/think)
8 |
9 | ThinkPHP5在保持快速开发和大道至简的核心理念不变的同时,PHP版本要求提升到5.4,对已有的CBD模式做了更深的强化,优化核心,减少依赖,基于全新的架构思想和命名空间实现,是ThinkPHP突破原有框架思路的颠覆之作,其主要特性包括:
10 |
11 | + 基于命名空间和众多PHP新特性
12 | + 核心功能组件化
13 | + 强化路由功能
14 | + 更灵活的控制器
15 | + 重构的模型和数据库类
16 | + 配置文件可分离
17 | + 重写的自动验证和完成
18 | + 简化扩展机制
19 | + API支持完善
20 | + 改进的Log类
21 | + 命令行访问支持
22 | + REST支持
23 | + 引导文件支持
24 | + 方便的自动生成定义
25 | + 真正惰性加载
26 | + 分布式环境支持
27 | + 更多的社交类库
28 |
29 | > ThinkPHP5的运行环境要求PHP5.4以上。
30 |
31 | 详细开发文档参考 [ThinkPHP5完全开发手册](http://www.kancloud.cn/manual/thinkphp5)
32 |
33 | ## 目录结构
34 |
35 | 初始的目录结构如下:
36 |
37 | ~~~
38 | www WEB部署目录(或者子目录)
39 | ├─application 应用目录
40 | │ ├─common 公共模块目录(可以更改)
41 | │ ├─module_name 模块目录
42 | │ │ ├─config.php 模块配置文件
43 | │ │ ├─common.php 模块函数文件
44 | │ │ ├─controller 控制器目录
45 | │ │ ├─model 模型目录
46 | │ │ ├─view 视图目录
47 | │ │ └─ ... 更多类库目录
48 | │ │
49 | │ ├─command.php 命令行工具配置文件
50 | │ ├─common.php 公共函数文件
51 | │ ├─config.php 公共配置文件
52 | │ ├─route.php 路由配置文件
53 | │ ├─tags.php 应用行为扩展定义文件
54 | │ └─database.php 数据库配置文件
55 | │
56 | ├─public WEB目录(对外访问目录)
57 | │ ├─index.php 入口文件
58 | │ ├─router.php 快速测试文件
59 | │ └─.htaccess 用于apache的重写
60 | │
61 | ├─thinkphp 框架系统目录
62 | │ ├─lang 语言文件目录
63 | │ ├─library 框架类库目录
64 | │ │ ├─think Think类库包目录
65 | │ │ └─traits 系统Trait目录
66 | │ │
67 | │ ├─tpl 系统模板目录
68 | │ ├─base.php 基础定义文件
69 | │ ├─console.php 控制台入口文件
70 | │ ├─convention.php 框架惯例配置文件
71 | │ ├─helper.php 助手函数文件
72 | │ ├─phpunit.xml phpunit配置文件
73 | │ └─start.php 框架入口文件
74 | │
75 | ├─extend 扩展类库目录
76 | ├─runtime 应用的运行时目录(可写,可定制)
77 | ├─vendor 第三方类库目录(Composer依赖库)
78 | ├─build.php 自动生成定义文件(参考)
79 | ├─composer.json composer 定义文件
80 | ├─LICENSE.txt 授权说明文件
81 | ├─README.md README 文件
82 | ├─think 命令行入口文件
83 | ~~~
84 |
85 | > router.php用于php自带webserver支持,可用于快速测试
86 | > 切换到public目录后,启动命令:php -S localhost:8888 router.php
87 | > 上面的目录结构和名称是可以改变的,这取决于你的入口文件和配置参数。
88 |
89 | ## 命名规范
90 |
91 | `ThinkPHP5`遵循PSR-2命名规范和PSR-4自动加载规范,并且注意如下规范:
92 |
93 | ### 目录和文件
94 |
95 | * 目录不强制规范,驼峰和小写+下划线模式均支持;
96 | * 类库、函数文件统一以`.php`为后缀;
97 | * 类的文件名均以命名空间定义,并且命名空间的路径和类库文件所在路径一致;
98 | * 类名和类文件名保持一致,统一采用驼峰法命名(首字母大写);
99 |
100 | ### 函数和类、属性命名
101 | * 类的命名采用驼峰法,并且首字母大写,例如 `User`、`UserType`,默认不需要添加后缀,例如`UserController`应该直接命名为`User`;
102 | * 函数的命名使用小写字母和下划线(小写字母开头)的方式,例如 `get_client_ip`;
103 | * 方法的命名使用驼峰法,并且首字母小写,例如 `getUserName`;
104 | * 属性的命名使用驼峰法,并且首字母小写,例如 `tableName`、`instance`;
105 | * 以双下划线“__”打头的函数或方法作为魔法方法,例如 `__call` 和 `__autoload`;
106 |
107 | ### 常量和配置
108 | * 常量以大写字母和下划线命名,例如 `APP_PATH`和 `THINK_PATH`;
109 | * 配置参数以小写字母和下划线命名,例如 `url_route_on` 和`url_convert`;
110 |
111 | ### 数据表和字段
112 | * 数据表和字段采用小写加下划线方式命名,并注意字段名不要以下划线开头,例如 `think_user` 表和 `user_name`字段,不建议使用驼峰和中文作为数据表字段命名。
113 |
114 | ## 参与开发
115 | 请参阅 [ThinkPHP5 核心框架包](https://github.com/top-think/framework)。
116 |
117 | ## 版权信息
118 |
119 | ThinkPHP遵循Apache2开源协议发布,并提供免费使用。
120 |
121 | 本项目包含的第三方源码和二进制文件之版权信息另行标注。
122 |
123 | 版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn)
124 |
125 | All rights reserved。
126 |
127 | ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
128 |
129 | 更多细节参阅 [LICENSE.txt](LICENSE.txt)
130 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman/Lib/Timer.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Lib;
15 |
16 | use Workerman\Events\EventInterface;
17 | use Exception;
18 |
19 | /**
20 | * Timer.
21 | *
22 | * example:
23 | * Workerman\Lib\Timer::add($time_interval, callback, array($arg1, $arg2..));
24 | */
25 | class Timer
26 | {
27 | /**
28 | * Tasks that based on ALARM signal.
29 | * [
30 | * run_time => [[$func, $args, $persistent, time_interval],[$func, $args, $persistent, time_interval],..]],
31 | * run_time => [[$func, $args, $persistent, time_interval],[$func, $args, $persistent, time_interval],..]],
32 | * ..
33 | * ]
34 | *
35 | * @var array
36 | */
37 | protected static $_tasks = array();
38 |
39 | /**
40 | * event
41 | *
42 | * @var \Workerman\Events\EventInterface
43 | */
44 | protected static $_event = null;
45 |
46 | /**
47 | * Init.
48 | *
49 | * @param \Workerman\Events\EventInterface $event
50 | * @return void
51 | */
52 | public static function init($event = null)
53 | {
54 | if ($event) {
55 | self::$_event = $event;
56 | } else {
57 | pcntl_signal(SIGALRM, array('\Workerman\Lib\Timer', 'signalHandle'), false);
58 | }
59 | }
60 |
61 | /**
62 | * ALARM signal handler.
63 | *
64 | * @return void
65 | */
66 | public static function signalHandle()
67 | {
68 | if (!self::$_event) {
69 | pcntl_alarm(1);
70 | self::tick();
71 | }
72 | }
73 |
74 | /**
75 | * Add a timer.
76 | *
77 | * @param int $time_interval
78 | * @param callback $func
79 | * @param mixed $args
80 | * @param bool $persistent
81 | * @return bool
82 | */
83 | public static function add($time_interval, $func, $args = array(), $persistent = true)
84 | {
85 | if ($time_interval <= 0) {
86 | echo new Exception("bad time_interval");
87 | return false;
88 | }
89 |
90 | if (self::$_event) {
91 | return self::$_event->add($time_interval,
92 | $persistent ? EventInterface::EV_TIMER : EventInterface::EV_TIMER_ONCE, $func, $args);
93 | }
94 |
95 | if (!is_callable($func)) {
96 | echo new Exception("not callable");
97 | return false;
98 | }
99 |
100 | if (empty(self::$_tasks)) {
101 | pcntl_alarm(1);
102 | }
103 |
104 | $time_now = time();
105 | $run_time = $time_now + $time_interval;
106 | if (!isset(self::$_tasks[$run_time])) {
107 | self::$_tasks[$run_time] = array();
108 | }
109 | self::$_tasks[$run_time][] = array($func, (array)$args, $persistent, $time_interval);
110 | return true;
111 | }
112 |
113 |
114 | /**
115 | * Tick.
116 | *
117 | * @return void
118 | */
119 | public static function tick()
120 | {
121 | if (empty(self::$_tasks)) {
122 | pcntl_alarm(0);
123 | return;
124 | }
125 |
126 | $time_now = time();
127 | foreach (self::$_tasks as $run_time => $task_data) {
128 | if ($time_now >= $run_time) {
129 | foreach ($task_data as $index => $one_task) {
130 | $task_func = $one_task[0];
131 | $task_args = $one_task[1];
132 | $persistent = $one_task[2];
133 | $time_interval = $one_task[3];
134 | try {
135 | call_user_func_array($task_func, $task_args);
136 | } catch (\Exception $e) {
137 | echo $e;
138 | }
139 | if ($persistent) {
140 | self::add($time_interval, $task_func, $task_args);
141 | }
142 | }
143 | unset(self::$_tasks[$run_time]);
144 | }
145 | }
146 | }
147 |
148 | /**
149 | * Remove a timer.
150 | *
151 | * @param mixed $timer_id
152 | * @return bool
153 | */
154 | public static function del($timer_id)
155 | {
156 | if (self::$_event) {
157 | return self::$_event->del($timer_id, EventInterface::EV_TIMER);
158 | }
159 |
160 | return false;
161 | }
162 |
163 | /**
164 | * Remove all timers.
165 | *
166 | * @return void
167 | */
168 | public static function delAll()
169 | {
170 | self::$_tasks = array();
171 | pcntl_alarm(0);
172 | if (self::$_event) {
173 | self::$_event->clearAllTimer();
174 | }
175 | }
176 | }
177 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman-for-win/Lib/Timer.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Lib;
15 |
16 | use Workerman\Events\EventInterface;
17 | use Exception;
18 |
19 | /**
20 | * Timer.
21 | *
22 | * example:
23 | * Workerman\Lib\Timer::add($time_interval, callback, array($arg1, $arg2..));
24 | */
25 | class Timer
26 | {
27 | /**
28 | * Tasks that based on ALARM signal.
29 | * [
30 | * run_time => [[$func, $args, $persistent, time_interval],[$func, $args, $persistent, time_interval],..]],
31 | * run_time => [[$func, $args, $persistent, time_interval],[$func, $args, $persistent, time_interval],..]],
32 | * ..
33 | * ]
34 | *
35 | * @var array
36 | */
37 | protected static $_tasks = array();
38 |
39 | /**
40 | * event
41 | *
42 | * @var \Workerman\Events\EventInterface
43 | */
44 | protected static $_event = null;
45 |
46 | /**
47 | * Init.
48 | *
49 | * @param \Workerman\Events\EventInterface $event
50 | * @return void
51 | */
52 | public static function init($event = null)
53 | {
54 | if ($event) {
55 | self::$_event = $event;
56 | } else {
57 | pcntl_signal(SIGALRM, array('\Workerman\Lib\Timer', 'signalHandle'), false);
58 | }
59 | }
60 |
61 | /**
62 | * ALARM signal handler.
63 | *
64 | * @return void
65 | */
66 | public static function signalHandle()
67 | {
68 | if (!self::$_event) {
69 | pcntl_alarm(1);
70 | self::tick();
71 | }
72 | }
73 |
74 | /**
75 | * Add a timer.
76 | *
77 | * @param int $time_interval
78 | * @param callback $func
79 | * @param mixed $args
80 | * @param bool $persistent
81 | * @return bool
82 | */
83 | public static function add($time_interval, $func, $args = array(), $persistent = true)
84 | {
85 | if ($time_interval <= 0) {
86 | echo new Exception("bad time_interval");
87 | return false;
88 | }
89 |
90 | if (self::$_event) {
91 | return self::$_event->add($time_interval,
92 | $persistent ? EventInterface::EV_TIMER : EventInterface::EV_TIMER_ONCE, $func, $args);
93 | }
94 |
95 | if (!is_callable($func)) {
96 | echo new Exception("not callable");
97 | return false;
98 | }
99 |
100 | if (empty(self::$_tasks)) {
101 | pcntl_alarm(1);
102 | }
103 |
104 | $time_now = time();
105 | $run_time = $time_now + $time_interval;
106 | if (!isset(self::$_tasks[$run_time])) {
107 | self::$_tasks[$run_time] = array();
108 | }
109 | self::$_tasks[$run_time][] = array($func, (array)$args, $persistent, $time_interval);
110 | return true;
111 | }
112 |
113 |
114 | /**
115 | * Tick.
116 | *
117 | * @return void
118 | */
119 | public static function tick()
120 | {
121 | if (empty(self::$_tasks)) {
122 | pcntl_alarm(0);
123 | return;
124 | }
125 |
126 | $time_now = time();
127 | foreach (self::$_tasks as $run_time => $task_data) {
128 | if ($time_now >= $run_time) {
129 | foreach ($task_data as $index => $one_task) {
130 | $task_func = $one_task[0];
131 | $task_args = $one_task[1];
132 | $persistent = $one_task[2];
133 | $time_interval = $one_task[3];
134 | try {
135 | call_user_func_array($task_func, $task_args);
136 | } catch (\Exception $e) {
137 | echo $e;
138 | }
139 | if ($persistent) {
140 | self::add($time_interval, $task_func, $task_args);
141 | }
142 | }
143 | unset(self::$_tasks[$run_time]);
144 | }
145 | }
146 | }
147 |
148 | /**
149 | * Remove a timer.
150 | *
151 | * @param mixed $timer_id
152 | * @return bool
153 | */
154 | public static function del($timer_id)
155 | {
156 | if (self::$_event) {
157 | return self::$_event->del($timer_id, EventInterface::EV_TIMER);
158 | }
159 |
160 | return false;
161 | }
162 |
163 | /**
164 | * Remove all timers.
165 | *
166 | * @return void
167 | */
168 | public static function delAll()
169 | {
170 | self::$_tasks = array();
171 | pcntl_alarm(0);
172 | if (self::$_event) {
173 | self::$_event->clearAllTimer();
174 | }
175 | }
176 | }
177 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman/Events/Ev.php:
--------------------------------------------------------------------------------
1 |
10 | * @link http://www.workerman.net/
11 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
12 | */
13 | namespace Workerman\Events;
14 |
15 | use Workerman\Worker;
16 |
17 | /**
18 | * ev eventloop
19 | */
20 | class Ev implements EventInterface
21 | {
22 | /**
23 | * All listeners for read/write event.
24 | *
25 | * @var array
26 | */
27 | protected $_allEvents = array();
28 |
29 | /**
30 | * Event listeners of signal.
31 | *
32 | * @var array
33 | */
34 | protected $_eventSignal = array();
35 |
36 | /**
37 | * All timer event listeners.
38 | * [func, args, event, flag, time_interval]
39 | *
40 | * @var array
41 | */
42 | protected $_eventTimer = array();
43 |
44 | /**
45 | * Timer id.
46 | *
47 | * @var int
48 | */
49 | protected static $_timerId = 1;
50 |
51 | /**
52 | * Add a timer.
53 | * {@inheritdoc}
54 | */
55 | public function add($fd, $flag, $func, $args = null)
56 | {
57 | $callback = function ($event, $socket) use ($fd, $func) {
58 | try {
59 | call_user_func($func, $fd);
60 | } catch (\Exception $e) {
61 | Worker::log($e);
62 | exit(250);
63 | } catch (\Error $e) {
64 | Worker::log($e);
65 | exit(250);
66 | }
67 | };
68 |
69 | switch ($flag) {
70 | case self::EV_SIGNAL:
71 | $event = new \EvSignal($fd, $callback);
72 | $this->_eventSignal[$fd] = $event;
73 | return true;
74 | case self::EV_TIMER:
75 | case self::EV_TIMER_ONCE:
76 | $repeat = $flag == self::EV_TIMER_ONCE ? 0 : $fd;
77 | $param = array($func, (array)$args, $flag, $fd, self::$_timerId);
78 | $event = new \EvTimer($fd, $repeat, array($this, 'timerCallback'), $param);
79 | $this->_eventTimer[self::$_timerId] = $event;
80 | return self::$_timerId++;
81 | default :
82 | $fd_key = (int)$fd;
83 | $real_flag = $flag === self::EV_READ ? \Ev::READ : \Ev::WRITE;
84 | $event = new \EvIo($fd, $real_flag, $callback);
85 | $this->_allEvents[$fd_key][$flag] = $event;
86 | return true;
87 | }
88 |
89 | }
90 |
91 | /**
92 | * Remove a timer.
93 | * {@inheritdoc}
94 | */
95 | public function del($fd, $flag)
96 | {
97 | switch ($flag) {
98 | case self::EV_READ:
99 | case self::EV_WRITE:
100 | $fd_key = (int)$fd;
101 | if (isset($this->_allEvents[$fd_key][$flag])) {
102 | $this->_allEvents[$fd_key][$flag]->stop();
103 | unset($this->_allEvents[$fd_key][$flag]);
104 | }
105 | if (empty($this->_allEvents[$fd_key])) {
106 | unset($this->_allEvents[$fd_key]);
107 | }
108 | break;
109 | case self::EV_SIGNAL:
110 | $fd_key = (int)$fd;
111 | if (isset($this->_eventSignal[$fd_key])) {
112 | $this->_allEvents[$fd_key][$flag]->stop();
113 | unset($this->_eventSignal[$fd_key]);
114 | }
115 | break;
116 | case self::EV_TIMER:
117 | case self::EV_TIMER_ONCE:
118 | if (isset($this->_eventTimer[$fd])) {
119 | $this->_eventTimer[$fd]->stop();
120 | unset($this->_eventTimer[$fd]);
121 | }
122 | break;
123 | }
124 | return true;
125 | }
126 |
127 | /**
128 | * Timer callback.
129 | *
130 | * @param \EvWatcher $event
131 | */
132 | public function timerCallback($event)
133 | {
134 | $param = $event->data;
135 | $timer_id = $param[4];
136 | if ($param[2] === self::EV_TIMER_ONCE) {
137 | $this->_eventTimer[$timer_id]->stop();
138 | unset($this->_eventTimer[$timer_id]);
139 | }
140 | try {
141 | call_user_func_array($param[0], $param[1]);
142 | } catch (\Exception $e) {
143 | Worker::log($e);
144 | exit(250);
145 | } catch (\Error $e) {
146 | Worker::log($e);
147 | exit(250);
148 | }
149 | }
150 |
151 | /**
152 | * Remove all timers.
153 | *
154 | * @return void
155 | */
156 | public function clearAllTimer()
157 | {
158 | foreach ($this->_eventTimer as $event) {
159 | $event->stop();
160 | }
161 | $this->_eventTimer = array();
162 | }
163 |
164 | /**
165 | * Main loop.
166 | *
167 | * @see EventInterface::loop()
168 | */
169 | public function loop()
170 | {
171 | \Ev::run();
172 | }
173 | }
174 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman-for-win/Events/Ev.php:
--------------------------------------------------------------------------------
1 |
10 | * @link http://www.workerman.net/
11 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
12 | */
13 | namespace Workerman\Events;
14 |
15 | use Workerman\Worker;
16 |
17 | /**
18 | * ev eventloop
19 | */
20 | class Ev implements EventInterface
21 | {
22 | /**
23 | * All listeners for read/write event.
24 | *
25 | * @var array
26 | */
27 | protected $_allEvents = array();
28 |
29 | /**
30 | * Event listeners of signal.
31 | *
32 | * @var array
33 | */
34 | protected $_eventSignal = array();
35 |
36 | /**
37 | * All timer event listeners.
38 | * [func, args, event, flag, time_interval]
39 | *
40 | * @var array
41 | */
42 | protected $_eventTimer = array();
43 |
44 | /**
45 | * Timer id.
46 | *
47 | * @var int
48 | */
49 | protected static $_timerId = 1;
50 |
51 | /**
52 | * Add a timer.
53 | * {@inheritdoc}
54 | */
55 | public function add($fd, $flag, $func, $args = null)
56 | {
57 | $callback = function ($event, $socket) use ($fd, $func) {
58 | try {
59 | call_user_func($func, $fd);
60 | } catch (\Exception $e) {
61 | Worker::log($e);
62 | exit(250);
63 | } catch (\Error $e) {
64 | Worker::log($e);
65 | exit(250);
66 | }
67 | };
68 |
69 | switch ($flag) {
70 | case self::EV_SIGNAL:
71 | $event = new \EvSignal($fd, $callback);
72 | $this->_eventSignal[$fd] = $event;
73 | return true;
74 | case self::EV_TIMER:
75 | case self::EV_TIMER_ONCE:
76 | $repeat = $flag == self::EV_TIMER_ONCE ? 0 : $fd;
77 | $param = array($func, (array)$args, $flag, $fd, self::$_timerId);
78 | $event = new \EvTimer($fd, $repeat, array($this, 'timerCallback'), $param);
79 | $this->_eventTimer[self::$_timerId] = $event;
80 | return self::$_timerId++;
81 | default :
82 | $fd_key = (int)$fd;
83 | $real_flag = $flag === self::EV_READ ? \Ev::READ : \Ev::WRITE;
84 | $event = new \EvIo($fd, $real_flag, $callback);
85 | $this->_allEvents[$fd_key][$flag] = $event;
86 | return true;
87 | }
88 |
89 | }
90 |
91 | /**
92 | * Remove a timer.
93 | * {@inheritdoc}
94 | */
95 | public function del($fd, $flag)
96 | {
97 | switch ($flag) {
98 | case self::EV_READ:
99 | case self::EV_WRITE:
100 | $fd_key = (int)$fd;
101 | if (isset($this->_allEvents[$fd_key][$flag])) {
102 | $this->_allEvents[$fd_key][$flag]->stop();
103 | unset($this->_allEvents[$fd_key][$flag]);
104 | }
105 | if (empty($this->_allEvents[$fd_key])) {
106 | unset($this->_allEvents[$fd_key]);
107 | }
108 | break;
109 | case self::EV_SIGNAL:
110 | $fd_key = (int)$fd;
111 | if (isset($this->_eventSignal[$fd_key])) {
112 | $this->_allEvents[$fd_key][$flag]->stop();
113 | unset($this->_eventSignal[$fd_key]);
114 | }
115 | break;
116 | case self::EV_TIMER:
117 | case self::EV_TIMER_ONCE:
118 | if (isset($this->_eventTimer[$fd])) {
119 | $this->_eventTimer[$fd]->stop();
120 | unset($this->_eventTimer[$fd]);
121 | }
122 | break;
123 | }
124 | return true;
125 | }
126 |
127 | /**
128 | * Timer callback.
129 | *
130 | * @param \EvWatcher $event
131 | */
132 | public function timerCallback($event)
133 | {
134 | $param = $event->data;
135 | $timer_id = $param[4];
136 | if ($param[2] === self::EV_TIMER_ONCE) {
137 | $this->_eventTimer[$timer_id]->stop();
138 | unset($this->_eventTimer[$timer_id]);
139 | }
140 | try {
141 | call_user_func_array($param[0], $param[1]);
142 | } catch (\Exception $e) {
143 | Worker::log($e);
144 | exit(250);
145 | } catch (\Error $e) {
146 | Worker::log($e);
147 | exit(250);
148 | }
149 | }
150 |
151 | /**
152 | * Remove all timers.
153 | *
154 | * @return void
155 | */
156 | public function clearAllTimer()
157 | {
158 | foreach ($this->_eventTimer as $event) {
159 | $event->stop();
160 | }
161 | $this->_eventTimer = array();
162 | }
163 |
164 | /**
165 | * Main loop.
166 | *
167 | * @see EventInterface::loop()
168 | */
169 | public function loop()
170 | {
171 | \Ev::run();
172 | }
173 | }
174 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman/Events/Event.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright 有个鬼<42765633@qq.com>
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Events;
15 |
16 | use Workerman\Worker;
17 |
18 | /**
19 | * libevent eventloop
20 | */
21 | class Event implements EventInterface
22 | {
23 | /**
24 | * Event base.
25 | * @var object
26 | */
27 | protected $_eventBase = null;
28 |
29 | /**
30 | * All listeners for read/write event.
31 | * @var array
32 | */
33 | protected $_allEvents = array();
34 |
35 | /**
36 | * Event listeners of signal.
37 | * @var array
38 | */
39 | protected $_eventSignal = array();
40 |
41 | /**
42 | * All timer event listeners.
43 | * [func, args, event, flag, time_interval]
44 | * @var array
45 | */
46 | protected $_eventTimer = array();
47 |
48 | /**
49 | * Timer id.
50 | * @var int
51 | */
52 | protected static $_timerId = 1;
53 |
54 | /**
55 | * construct
56 | * @return void
57 | */
58 | public function __construct()
59 | {
60 | $this->_eventBase = new \EventBase();
61 | }
62 |
63 | /**
64 | * @see EventInterface::add()
65 | */
66 | public function add($fd, $flag, $func, $args=array())
67 | {
68 | switch ($flag) {
69 | case self::EV_SIGNAL:
70 |
71 | $fd_key = (int)$fd;
72 | $event = \Event::signal($this->_eventBase, $fd, $func);
73 | if (!$event||!$event->add()) {
74 | return false;
75 | }
76 | $this->_eventSignal[$fd_key] = $event;
77 | return true;
78 |
79 | case self::EV_TIMER:
80 | case self::EV_TIMER_ONCE:
81 |
82 | $param = array($func, (array)$args, $flag, $fd, self::$_timerId);
83 | $event = new \Event($this->_eventBase, -1, \Event::TIMEOUT|\Event::PERSIST, array($this, "timerCallback"), $param);
84 | if (!$event||!$event->addTimer($fd)) {
85 | return false;
86 | }
87 | $this->_eventTimer[self::$_timerId] = $event;
88 | return self::$_timerId++;
89 |
90 | default :
91 | $fd_key = (int)$fd;
92 | $real_flag = $flag === self::EV_READ ? \Event::READ | \Event::PERSIST : \Event::WRITE | \Event::PERSIST;
93 | $event = new \Event($this->_eventBase, $fd, $real_flag, $func, $fd);
94 | if (!$event||!$event->add()) {
95 | return false;
96 | }
97 | $this->_allEvents[$fd_key][$flag] = $event;
98 | return true;
99 | }
100 | }
101 |
102 | /**
103 | * @see Events\EventInterface::del()
104 | */
105 | public function del($fd, $flag)
106 | {
107 | switch ($flag) {
108 |
109 | case self::EV_READ:
110 | case self::EV_WRITE:
111 |
112 | $fd_key = (int)$fd;
113 | if (isset($this->_allEvents[$fd_key][$flag])) {
114 | $this->_allEvents[$fd_key][$flag]->del();
115 | unset($this->_allEvents[$fd_key][$flag]);
116 | }
117 | if (empty($this->_allEvents[$fd_key])) {
118 | unset($this->_allEvents[$fd_key]);
119 | }
120 | break;
121 |
122 | case self::EV_SIGNAL:
123 |
124 | $fd_key = (int)$fd;
125 | if (isset($this->_eventSignal[$fd_key])) {
126 | $this->_allEvents[$fd_key][$flag]->del();
127 | unset($this->_eventSignal[$fd_key]);
128 | }
129 | break;
130 |
131 | case self::EV_TIMER:
132 | case self::EV_TIMER_ONCE:
133 | if (isset($this->_eventTimer[$fd])) {
134 | $this->_eventTimer[$fd]->del();
135 | unset($this->_eventTimer[$fd]);
136 | }
137 | break;
138 | }
139 | return true;
140 | }
141 |
142 | /**
143 | * Timer callback.
144 | * @param null $fd
145 | * @param int $what
146 | * @param int $timer_id
147 | */
148 | public function timerCallback($fd, $what, $param)
149 | {
150 | $timer_id = $param[4];
151 |
152 | if ($param[2] === self::EV_TIMER_ONCE) {
153 | $this->_eventTimer[$timer_id]->del();
154 | unset($this->_eventTimer[$timer_id]);
155 | }
156 |
157 | try {
158 | call_user_func_array($param[0], $param[1]);
159 | } catch (\Exception $e) {
160 | Worker::log($e);
161 | exit(250);
162 | } catch (\Error $e) {
163 | Worker::log($e);
164 | exit(250);
165 | }
166 | }
167 |
168 | /**
169 | * @see Events\EventInterface::clearAllTimer()
170 | * @return void
171 | */
172 | public function clearAllTimer()
173 | {
174 | foreach ($this->_eventTimer as $event) {
175 | $event->del();
176 | }
177 | $this->_eventTimer = array();
178 | }
179 |
180 |
181 | /**
182 | * @see EventInterface::loop()
183 | */
184 | public function loop()
185 | {
186 | $this->_eventBase->loop();
187 | }
188 | }
189 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman-for-win/Events/Event.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright 有个鬼<42765633@qq.com>
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Events;
15 |
16 | use Workerman\Worker;
17 |
18 | /**
19 | * libevent eventloop
20 | */
21 | class Event implements EventInterface
22 | {
23 | /**
24 | * Event base.
25 | * @var object
26 | */
27 | protected $_eventBase = null;
28 |
29 | /**
30 | * All listeners for read/write event.
31 | * @var array
32 | */
33 | protected $_allEvents = array();
34 |
35 | /**
36 | * Event listeners of signal.
37 | * @var array
38 | */
39 | protected $_eventSignal = array();
40 |
41 | /**
42 | * All timer event listeners.
43 | * [func, args, event, flag, time_interval]
44 | * @var array
45 | */
46 | protected $_eventTimer = array();
47 |
48 | /**
49 | * Timer id.
50 | * @var int
51 | */
52 | protected static $_timerId = 1;
53 |
54 | /**
55 | * construct
56 | * @return void
57 | */
58 | public function __construct()
59 | {
60 | $this->_eventBase = new \EventBase();
61 | }
62 |
63 | /**
64 | * @see EventInterface::add()
65 | */
66 | public function add($fd, $flag, $func, $args=array())
67 | {
68 | switch ($flag) {
69 | case self::EV_SIGNAL:
70 |
71 | $fd_key = (int)$fd;
72 | $event = \Event::signal($this->_eventBase, $fd, $func);
73 | if (!$event||!$event->add()) {
74 | return false;
75 | }
76 | $this->_eventSignal[$fd_key] = $event;
77 | return true;
78 |
79 | case self::EV_TIMER:
80 | case self::EV_TIMER_ONCE:
81 |
82 | $param = array($func, (array)$args, $flag, $fd, self::$_timerId);
83 | $event = new \Event($this->_eventBase, -1, \Event::TIMEOUT|\Event::PERSIST, array($this, "timerCallback"), $param);
84 | if (!$event||!$event->addTimer($fd)) {
85 | return false;
86 | }
87 | $this->_eventTimer[self::$_timerId] = $event;
88 | return self::$_timerId++;
89 |
90 | default :
91 | $fd_key = (int)$fd;
92 | $real_flag = $flag === self::EV_READ ? \Event::READ | \Event::PERSIST : \Event::WRITE | \Event::PERSIST;
93 | $event = new \Event($this->_eventBase, $fd, $real_flag, $func, $fd);
94 | if (!$event||!$event->add()) {
95 | return false;
96 | }
97 | $this->_allEvents[$fd_key][$flag] = $event;
98 | return true;
99 | }
100 | }
101 |
102 | /**
103 | * @see Events\EventInterface::del()
104 | */
105 | public function del($fd, $flag)
106 | {
107 | switch ($flag) {
108 |
109 | case self::EV_READ:
110 | case self::EV_WRITE:
111 |
112 | $fd_key = (int)$fd;
113 | if (isset($this->_allEvents[$fd_key][$flag])) {
114 | $this->_allEvents[$fd_key][$flag]->del();
115 | unset($this->_allEvents[$fd_key][$flag]);
116 | }
117 | if (empty($this->_allEvents[$fd_key])) {
118 | unset($this->_allEvents[$fd_key]);
119 | }
120 | break;
121 |
122 | case self::EV_SIGNAL:
123 |
124 | $fd_key = (int)$fd;
125 | if (isset($this->_eventSignal[$fd_key])) {
126 | $this->_allEvents[$fd_key][$flag]->del();
127 | unset($this->_eventSignal[$fd_key]);
128 | }
129 | break;
130 |
131 | case self::EV_TIMER:
132 | case self::EV_TIMER_ONCE:
133 | if (isset($this->_eventTimer[$fd])) {
134 | $this->_eventTimer[$fd]->del();
135 | unset($this->_eventTimer[$fd]);
136 | }
137 | break;
138 | }
139 | return true;
140 | }
141 |
142 | /**
143 | * Timer callback.
144 | * @param null $fd
145 | * @param int $what
146 | * @param int $timer_id
147 | */
148 | public function timerCallback($fd, $what, $param)
149 | {
150 | $timer_id = $param[4];
151 |
152 | if ($param[2] === self::EV_TIMER_ONCE) {
153 | $this->_eventTimer[$timer_id]->del();
154 | unset($this->_eventTimer[$timer_id]);
155 | }
156 |
157 | try {
158 | call_user_func_array($param[0], $param[1]);
159 | } catch (\Exception $e) {
160 | Worker::log($e);
161 | exit(250);
162 | } catch (\Error $e) {
163 | Worker::log($e);
164 | exit(250);
165 | }
166 | }
167 |
168 | /**
169 | * @see Events\EventInterface::clearAllTimer()
170 | * @return void
171 | */
172 | public function clearAllTimer()
173 | {
174 | foreach ($this->_eventTimer as $event) {
175 | $event->del();
176 | }
177 | $this->_eventTimer = array();
178 | }
179 |
180 |
181 | /**
182 | * @see EventInterface::loop()
183 | */
184 | public function loop()
185 | {
186 | $this->_eventBase->loop();
187 | }
188 | }
189 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman/Events/Libevent.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Events;
15 |
16 | use Workerman\Worker;
17 |
18 | /**
19 | * libevent eventloop
20 | */
21 | class Libevent implements EventInterface
22 | {
23 | /**
24 | * Event base.
25 | *
26 | * @var resource
27 | */
28 | protected $_eventBase = null;
29 |
30 | /**
31 | * All listeners for read/write event.
32 | *
33 | * @var array
34 | */
35 | protected $_allEvents = array();
36 |
37 | /**
38 | * Event listeners of signal.
39 | *
40 | * @var array
41 | */
42 | protected $_eventSignal = array();
43 |
44 | /**
45 | * All timer event listeners.
46 | * [func, args, event, flag, time_interval]
47 | *
48 | * @var array
49 | */
50 | protected $_eventTimer = array();
51 |
52 | /**
53 | * construct
54 | */
55 | public function __construct()
56 | {
57 | $this->_eventBase = event_base_new();
58 | }
59 |
60 | /**
61 | * {@inheritdoc}
62 | */
63 | public function add($fd, $flag, $func, $args = array())
64 | {
65 | switch ($flag) {
66 | case self::EV_SIGNAL:
67 | $fd_key = (int)$fd;
68 | $real_flag = EV_SIGNAL | EV_PERSIST;
69 | $this->_eventSignal[$fd_key] = event_new();
70 | if (!event_set($this->_eventSignal[$fd_key], $fd, $real_flag, $func, null)) {
71 | return false;
72 | }
73 | if (!event_base_set($this->_eventSignal[$fd_key], $this->_eventBase)) {
74 | return false;
75 | }
76 | if (!event_add($this->_eventSignal[$fd_key])) {
77 | return false;
78 | }
79 | return true;
80 | case self::EV_TIMER:
81 | case self::EV_TIMER_ONCE:
82 | $event = event_new();
83 | $timer_id = (int)$event;
84 | if (!event_set($event, 0, EV_TIMEOUT, array($this, 'timerCallback'), $timer_id)) {
85 | return false;
86 | }
87 |
88 | if (!event_base_set($event, $this->_eventBase)) {
89 | return false;
90 | }
91 |
92 | $time_interval = $fd * 1000000;
93 | if (!event_add($event, $time_interval)) {
94 | return false;
95 | }
96 | $this->_eventTimer[$timer_id] = array($func, (array)$args, $event, $flag, $time_interval);
97 | return $timer_id;
98 |
99 | default :
100 | $fd_key = (int)$fd;
101 | $real_flag = $flag === self::EV_READ ? EV_READ | EV_PERSIST : EV_WRITE | EV_PERSIST;
102 |
103 | $event = event_new();
104 |
105 | if (!event_set($event, $fd, $real_flag, $func, null)) {
106 | return false;
107 | }
108 |
109 | if (!event_base_set($event, $this->_eventBase)) {
110 | return false;
111 | }
112 |
113 | if (!event_add($event)) {
114 | return false;
115 | }
116 |
117 | $this->_allEvents[$fd_key][$flag] = $event;
118 |
119 | return true;
120 | }
121 |
122 | }
123 |
124 | /**
125 | * {@inheritdoc}
126 | */
127 | public function del($fd, $flag)
128 | {
129 | switch ($flag) {
130 | case self::EV_READ:
131 | case self::EV_WRITE:
132 | $fd_key = (int)$fd;
133 | if (isset($this->_allEvents[$fd_key][$flag])) {
134 | event_del($this->_allEvents[$fd_key][$flag]);
135 | unset($this->_allEvents[$fd_key][$flag]);
136 | }
137 | if (empty($this->_allEvents[$fd_key])) {
138 | unset($this->_allEvents[$fd_key]);
139 | }
140 | break;
141 | case self::EV_SIGNAL:
142 | $fd_key = (int)$fd;
143 | if (isset($this->_eventSignal[$fd_key])) {
144 | event_del($this->_eventSignal[$fd_key]);
145 | unset($this->_eventSignal[$fd_key]);
146 | }
147 | break;
148 | case self::EV_TIMER:
149 | case self::EV_TIMER_ONCE:
150 | // 这里 fd 为timerid
151 | if (isset($this->_eventTimer[$fd])) {
152 | event_del($this->_eventTimer[$fd][2]);
153 | unset($this->_eventTimer[$fd]);
154 | }
155 | break;
156 | }
157 | return true;
158 | }
159 |
160 | /**
161 | * Timer callback.
162 | *
163 | * @param mixed $_null1
164 | * @param int $_null2
165 | * @param mixed $timer_id
166 | */
167 | protected function timerCallback($_null1, $_null2, $timer_id)
168 | {
169 | if ($this->_eventTimer[$timer_id][3] === self::EV_TIMER) {
170 | event_add($this->_eventTimer[$timer_id][2], $this->_eventTimer[$timer_id][4]);
171 | }
172 | try {
173 | call_user_func_array($this->_eventTimer[$timer_id][0], $this->_eventTimer[$timer_id][1]);
174 | } catch (\Exception $e) {
175 | Worker::log($e);
176 | exit(250);
177 | } catch (\Error $e) {
178 | Worker::log($e);
179 | exit(250);
180 | }
181 | if (isset($this->_eventTimer[$timer_id]) && $this->_eventTimer[$timer_id][3] === self::EV_TIMER_ONCE) {
182 | $this->del($timer_id, self::EV_TIMER_ONCE);
183 | }
184 | }
185 |
186 | /**
187 | * {@inheritdoc}
188 | */
189 | public function clearAllTimer()
190 | {
191 | foreach ($this->_eventTimer as $task_data) {
192 | event_del($task_data[2]);
193 | }
194 | $this->_eventTimer = array();
195 | }
196 |
197 | /**
198 | * {@inheritdoc}
199 | */
200 | public function loop()
201 | {
202 | event_base_loop($this->_eventBase);
203 | }
204 | }
205 |
206 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman-for-win/Events/Libevent.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Events;
15 |
16 | use Workerman\Worker;
17 |
18 | /**
19 | * libevent eventloop
20 | */
21 | class Libevent implements EventInterface
22 | {
23 | /**
24 | * Event base.
25 | *
26 | * @var resource
27 | */
28 | protected $_eventBase = null;
29 |
30 | /**
31 | * All listeners for read/write event.
32 | *
33 | * @var array
34 | */
35 | protected $_allEvents = array();
36 |
37 | /**
38 | * Event listeners of signal.
39 | *
40 | * @var array
41 | */
42 | protected $_eventSignal = array();
43 |
44 | /**
45 | * All timer event listeners.
46 | * [func, args, event, flag, time_interval]
47 | *
48 | * @var array
49 | */
50 | protected $_eventTimer = array();
51 |
52 | /**
53 | * construct
54 | */
55 | public function __construct()
56 | {
57 | $this->_eventBase = event_base_new();
58 | }
59 |
60 | /**
61 | * {@inheritdoc}
62 | */
63 | public function add($fd, $flag, $func, $args = array())
64 | {
65 | switch ($flag) {
66 | case self::EV_SIGNAL:
67 | $fd_key = (int)$fd;
68 | $real_flag = EV_SIGNAL | EV_PERSIST;
69 | $this->_eventSignal[$fd_key] = event_new();
70 | if (!event_set($this->_eventSignal[$fd_key], $fd, $real_flag, $func, null)) {
71 | return false;
72 | }
73 | if (!event_base_set($this->_eventSignal[$fd_key], $this->_eventBase)) {
74 | return false;
75 | }
76 | if (!event_add($this->_eventSignal[$fd_key])) {
77 | return false;
78 | }
79 | return true;
80 | case self::EV_TIMER:
81 | case self::EV_TIMER_ONCE:
82 | $event = event_new();
83 | $timer_id = (int)$event;
84 | if (!event_set($event, 0, EV_TIMEOUT, array($this, 'timerCallback'), $timer_id)) {
85 | return false;
86 | }
87 |
88 | if (!event_base_set($event, $this->_eventBase)) {
89 | return false;
90 | }
91 |
92 | $time_interval = $fd * 1000000;
93 | if (!event_add($event, $time_interval)) {
94 | return false;
95 | }
96 | $this->_eventTimer[$timer_id] = array($func, (array)$args, $event, $flag, $time_interval);
97 | return $timer_id;
98 |
99 | default :
100 | $fd_key = (int)$fd;
101 | $real_flag = $flag === self::EV_READ ? EV_READ | EV_PERSIST : EV_WRITE | EV_PERSIST;
102 |
103 | $event = event_new();
104 |
105 | if (!event_set($event, $fd, $real_flag, $func, null)) {
106 | return false;
107 | }
108 |
109 | if (!event_base_set($event, $this->_eventBase)) {
110 | return false;
111 | }
112 |
113 | if (!event_add($event)) {
114 | return false;
115 | }
116 |
117 | $this->_allEvents[$fd_key][$flag] = $event;
118 |
119 | return true;
120 | }
121 |
122 | }
123 |
124 | /**
125 | * {@inheritdoc}
126 | */
127 | public function del($fd, $flag)
128 | {
129 | switch ($flag) {
130 | case self::EV_READ:
131 | case self::EV_WRITE:
132 | $fd_key = (int)$fd;
133 | if (isset($this->_allEvents[$fd_key][$flag])) {
134 | event_del($this->_allEvents[$fd_key][$flag]);
135 | unset($this->_allEvents[$fd_key][$flag]);
136 | }
137 | if (empty($this->_allEvents[$fd_key])) {
138 | unset($this->_allEvents[$fd_key]);
139 | }
140 | break;
141 | case self::EV_SIGNAL:
142 | $fd_key = (int)$fd;
143 | if (isset($this->_eventSignal[$fd_key])) {
144 | event_del($this->_eventSignal[$fd_key]);
145 | unset($this->_eventSignal[$fd_key]);
146 | }
147 | break;
148 | case self::EV_TIMER:
149 | case self::EV_TIMER_ONCE:
150 | // 这里 fd 为timerid
151 | if (isset($this->_eventTimer[$fd])) {
152 | event_del($this->_eventTimer[$fd][2]);
153 | unset($this->_eventTimer[$fd]);
154 | }
155 | break;
156 | }
157 | return true;
158 | }
159 |
160 | /**
161 | * Timer callback.
162 | *
163 | * @param mixed $_null1
164 | * @param int $_null2
165 | * @param mixed $timer_id
166 | */
167 | protected function timerCallback($_null1, $_null2, $timer_id)
168 | {
169 | if ($this->_eventTimer[$timer_id][3] === self::EV_TIMER) {
170 | event_add($this->_eventTimer[$timer_id][2], $this->_eventTimer[$timer_id][4]);
171 | }
172 | try {
173 | call_user_func_array($this->_eventTimer[$timer_id][0], $this->_eventTimer[$timer_id][1]);
174 | } catch (\Exception $e) {
175 | Worker::log($e);
176 | exit(250);
177 | } catch (\Error $e) {
178 | Worker::log($e);
179 | exit(250);
180 | }
181 | if (isset($this->_eventTimer[$timer_id]) && $this->_eventTimer[$timer_id][3] === self::EV_TIMER_ONCE) {
182 | $this->del($timer_id, self::EV_TIMER_ONCE);
183 | }
184 | }
185 |
186 | /**
187 | * {@inheritdoc}
188 | */
189 | public function clearAllTimer()
190 | {
191 | foreach ($this->_eventTimer as $task_data) {
192 | event_del($task_data[2]);
193 | }
194 | $this->_eventTimer = array();
195 | }
196 |
197 | /**
198 | * {@inheritdoc}
199 | */
200 | public function loop()
201 | {
202 | event_base_loop($this->_eventBase);
203 | }
204 | }
205 |
206 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman-for-win/Connection/AsyncTcpConnection.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Connection;
15 |
16 | use Workerman\Events\EventInterface;
17 | use Workerman\Worker;
18 | use Exception;
19 |
20 | /**
21 | * AsyncTcpConnection.
22 | */
23 | class AsyncTcpConnection extends TcpConnection
24 | {
25 | /**
26 | * Emitted when socket connection is successfully established.
27 | *
28 | * @var callback
29 | */
30 | public $onConnect = null;
31 |
32 | /**
33 | * Status.
34 | *
35 | * @var int
36 | */
37 | protected $_status = self::STATUS_INITIAL;
38 |
39 | /**
40 | * Remote host.
41 | *
42 | * @var string
43 | */
44 | protected $_remoteHost = '';
45 |
46 | /**
47 | * Connect start time.
48 | *
49 | * @var string
50 | */
51 | protected $_connectStartTime = 0;
52 |
53 | /**
54 | * PHP built-in protocols.
55 | *
56 | * @var array
57 | */
58 | protected static $_builtinTransports = array(
59 | 'tcp' => 'tcp',
60 | 'udp' => 'udp',
61 | 'unix' => 'unix',
62 | 'ssl' => 'ssl',
63 | 'sslv2' => 'sslv2',
64 | 'sslv3' => 'sslv3',
65 | 'tls' => 'tls'
66 | );
67 |
68 | /**
69 | * Transport layer protocol.
70 | *
71 | * @var string
72 | */
73 | public $transport = 'tcp';
74 |
75 | /**
76 | * Construct.
77 | *
78 | * @param string $remote_address
79 | * @throws Exception
80 | */
81 | public function __construct($remote_address)
82 | {
83 | // Get the application layer communication protocol and listening address.
84 | list($scheme, $address) = explode(':', $remote_address, 2);
85 | // Check application layer protocol class.
86 | if (!isset(self::$_builtinTransports[$scheme])) {
87 | $scheme = ucfirst($scheme);
88 | $this->protocol = '\\Protocols\\' . $scheme;
89 | if (!class_exists($this->protocol)) {
90 | $this->protocol = "\\Workerman\\Protocols\\$scheme";
91 | if (!class_exists($this->protocol)) {
92 | throw new Exception("class \\Protocols\\$scheme not exist");
93 | }
94 | }
95 | } else {
96 | $this->transport = self::$_builtinTransports[$scheme];
97 | }
98 |
99 | $this->_remoteAddress = substr($address, 2);
100 | $this->_remoteHost = substr($this->_remoteAddress, 0, strrpos($this->_remoteAddress, ':'));
101 | $this->id = self::$_idRecorder++;
102 | // For statistics.
103 | self::$statistics['connection_count']++;
104 | $this->maxSendBufferSize = self::$defaultMaxSendBufferSize;
105 | }
106 |
107 | /**
108 | * Do connect
109 | *
110 | * @return void
111 | */
112 | public function connect()
113 | {
114 | if ($this->_status !== self::STATUS_INITIAL && $this->_status !== self::STATUS_CLOSED && $this->_status !== self::STATUS_CLOSING) {
115 | return;
116 | }
117 | $this->_status = self::STATUS_CONNECTING;
118 | $this->_connectStartTime = microtime(true);
119 | // Open socket connection asynchronously.
120 | $this->_socket = stream_socket_client("{$this->transport}://{$this->_remoteAddress}", $errno, $errstr, 0,
121 | STREAM_CLIENT_ASYNC_CONNECT);
122 | // If failed attempt to emit onError callback.
123 | if (!$this->_socket) {
124 | $this->emitError(WORKERMAN_CONNECT_FAIL, $errstr);
125 | if ($this->_status === self::STATUS_CLOSING) {
126 | $this->destroy();
127 | }
128 | if ($this->_status === self::STATUS_CLOSED) {
129 | $this->onConnect = null;
130 | }
131 | return;
132 | }
133 | // Add socket to global event loop waiting connection is successfully established or faild.
134 | Worker::$globalEvent->add($this->_socket, EventInterface::EV_WRITE, array($this, 'checkConnection'));
135 | Worker::$globalEvent->add($this->_socket, EventInterface::EV_EXCEPT, array($this, 'checkConnection'));
136 | }
137 |
138 | /**
139 | * Get remote address.
140 | *
141 | * @return string
142 | */
143 | public function getRemoteHost()
144 | {
145 | return $this->_remoteHost;
146 | }
147 |
148 | /**
149 | * Try to emit onError callback.
150 | *
151 | * @param int $code
152 | * @param string $msg
153 | * @return void
154 | */
155 | protected function emitError($code, $msg)
156 | {
157 | $this->_status = self::STATUS_CLOSING;
158 | if ($this->onError) {
159 | try {
160 | call_user_func($this->onError, $this, $code, $msg);
161 | } catch (\Exception $e) {
162 | Worker::log($e);
163 | exit(250);
164 | } catch (\Error $e) {
165 | Worker::log($e);
166 | exit(250);
167 | }
168 | }
169 | }
170 |
171 | /**
172 | * Check connection is successfully established or faild.
173 | *
174 | * @param resource $socket
175 | * @return void
176 | */
177 | public function checkConnection($socket)
178 | {
179 | Worker::$globalEvent->del($socket, EventInterface::EV_EXCEPT);
180 | // Check socket state.
181 | if (stream_socket_get_name($socket, true)) {
182 | // Remove write listener.
183 | Worker::$globalEvent->del($socket, EventInterface::EV_WRITE);
184 | // Nonblocking.
185 | stream_set_blocking($socket, 0);
186 | stream_set_read_buffer($socket, 0);
187 | // Try to open keepalive for tcp and disable Nagle algorithm.
188 | if (function_exists('socket_import_stream') && $this->transport === 'tcp') {
189 | $raw_socket = socket_import_stream($socket);
190 | socket_set_option($raw_socket, SOL_SOCKET, SO_KEEPALIVE, 1);
191 | socket_set_option($raw_socket, SOL_TCP, TCP_NODELAY, 1);
192 | }
193 | // Register a listener waiting read event.
194 | Worker::$globalEvent->add($socket, EventInterface::EV_READ, array($this, 'baseRead'));
195 | // There are some data waiting to send.
196 | if ($this->_sendBuffer) {
197 | Worker::$globalEvent->add($socket, EventInterface::EV_WRITE, array($this, 'baseWrite'));
198 | }
199 | $this->_status = self::STATUS_ESTABLISH;
200 | $this->_remoteAddress = stream_socket_get_name($socket, true);
201 | // Try to emit onConnect callback.
202 | if ($this->onConnect) {
203 | try {
204 | call_user_func($this->onConnect, $this);
205 | } catch (\Exception $e) {
206 | Worker::log($e);
207 | exit(250);
208 | } catch (\Error $e) {
209 | Worker::log($e);
210 | exit(250);
211 | }
212 | }
213 | } else {
214 | // Connection failed.
215 | $this->emitError(WORKERMAN_CONNECT_FAIL, 'connect ' . $this->_remoteAddress . ' fail after ' . round(microtime(true) - $this->_connectStartTime, 4) . ' seconds');
216 | if ($this->_status === self::STATUS_CLOSING) {
217 | $this->destroy();
218 | }
219 | if ($this->_status === self::STATUS_CLOSED) {
220 | $this->onConnect = null;
221 | }
222 | }
223 | }
224 | }
225 |
--------------------------------------------------------------------------------
/vendor/composer/installed.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "topthink/think-installer",
4 | "version": "v1.0.10",
5 | "version_normalized": "1.0.10.0",
6 | "source": {
7 | "type": "git",
8 | "url": "https://github.com/top-think/think-installer.git",
9 | "reference": "ae50760ebd7c687c7a8573db2cfa94a41e5100e3"
10 | },
11 | "dist": {
12 | "type": "zip",
13 | "url": "https://packagist.phpcomposer.com/files/top-think/think-installer/ae50760ebd7c687c7a8573db2cfa94a41e5100e3.zip",
14 | "reference": "ae50760ebd7c687c7a8573db2cfa94a41e5100e3",
15 | "shasum": ""
16 | },
17 | "require": {
18 | "composer-plugin-api": "^1.0"
19 | },
20 | "require-dev": {
21 | "composer/composer": "1.0.*@dev"
22 | },
23 | "time": "2016-09-23 04:04:44",
24 | "type": "composer-plugin",
25 | "extra": {
26 | "class": "think\\composer\\Plugin"
27 | },
28 | "installation-source": "dist",
29 | "autoload": {
30 | "psr-4": {
31 | "think\\composer\\": "src"
32 | }
33 | },
34 | "notification-url": "https://packagist.org/downloads/",
35 | "license": [
36 | "Apache-2.0"
37 | ],
38 | "authors": [
39 | {
40 | "name": "yunwuxin",
41 | "email": "448901948@qq.com"
42 | }
43 | ]
44 | },
45 | {
46 | "name": "topthink/think-worker",
47 | "version": "v1.0.1",
48 | "version_normalized": "1.0.1.0",
49 | "source": {
50 | "type": "git",
51 | "url": "https://github.com/top-think/think-worker.git",
52 | "reference": "b609ff5e38dbb7194aab027d2b2c6b31a7ed1bd1"
53 | },
54 | "dist": {
55 | "type": "zip",
56 | "url": "https://packagist.phpcomposer.com/files/top-think/think-worker/b609ff5e38dbb7194aab027d2b2c6b31a7ed1bd1.zip",
57 | "reference": "b609ff5e38dbb7194aab027d2b2c6b31a7ed1bd1",
58 | "shasum": ""
59 | },
60 | "require": {
61 | "workerman/workerman": "^3.3.0"
62 | },
63 | "time": "2016-10-08 06:07:03",
64 | "type": "library",
65 | "installation-source": "dist",
66 | "autoload": {
67 | "psr-4": {
68 | "think\\worker\\": "src"
69 | },
70 | "files": []
71 | },
72 | "notification-url": "https://packagist.org/downloads/",
73 | "license": [
74 | "Apache-2.0"
75 | ],
76 | "authors": [
77 | {
78 | "name": "liu21st",
79 | "email": "liu21st@gmail.com"
80 | }
81 | ],
82 | "description": "workerman extend for thinkphp5"
83 | },
84 | {
85 | "name": "workerman/workerman-for-win",
86 | "version": "v3.3.2",
87 | "version_normalized": "3.3.2.0",
88 | "source": {
89 | "type": "git",
90 | "url": "https://github.com/walkor/workerman-for-win.git",
91 | "reference": "40e8d204fa0b3cf845f2ac1cb8d97fa7e11ddf37"
92 | },
93 | "dist": {
94 | "type": "zip",
95 | "url": "https://packagist.phpcomposer.com/files/walkor/workerman-for-win/40e8d204fa0b3cf845f2ac1cb8d97fa7e11ddf37.zip",
96 | "reference": "40e8d204fa0b3cf845f2ac1cb8d97fa7e11ddf37",
97 | "shasum": ""
98 | },
99 | "require": {
100 | "php": ">=5.3"
101 | },
102 | "time": "2016-07-29 04:24:19",
103 | "type": "project",
104 | "installation-source": "dist",
105 | "autoload": {
106 | "psr-4": {
107 | "Workerman\\": "./"
108 | }
109 | },
110 | "notification-url": "https://packagist.org/downloads/",
111 | "license": [
112 | "MIT"
113 | ],
114 | "authors": [
115 | {
116 | "name": "walkor",
117 | "email": "walkor@workerman.net",
118 | "homepage": "http://www.workerman.net",
119 | "role": "Developer"
120 | }
121 | ],
122 | "description": "An asynchronous event driven PHP framework for easily building fast, scalable network applications.",
123 | "homepage": "http://www.workerman.net",
124 | "keywords": [
125 | "asynchronous",
126 | "event-loop"
127 | ]
128 | },
129 | {
130 | "name": "workerman/workerman",
131 | "version": "v3.3.4",
132 | "version_normalized": "3.3.4.0",
133 | "source": {
134 | "type": "git",
135 | "url": "https://github.com/walkor/Workerman.git",
136 | "reference": "d6a7f02c21660e328b7a5aaea82eeb59653b313d"
137 | },
138 | "dist": {
139 | "type": "zip",
140 | "url": "https://packagist.phpcomposer.com/files/walkor/Workerman/d6a7f02c21660e328b7a5aaea82eeb59653b313d.zip",
141 | "reference": "d6a7f02c21660e328b7a5aaea82eeb59653b313d",
142 | "shasum": ""
143 | },
144 | "require": {
145 | "php": ">=5.3"
146 | },
147 | "suggest": {
148 | "ext-libevent": "For better performance."
149 | },
150 | "time": "2016-09-19 02:15:51",
151 | "type": "project",
152 | "installation-source": "dist",
153 | "autoload": {
154 | "psr-4": {
155 | "Workerman\\": "./"
156 | }
157 | },
158 | "notification-url": "https://packagist.org/downloads/",
159 | "license": [
160 | "MIT"
161 | ],
162 | "authors": [
163 | {
164 | "name": "walkor",
165 | "email": "walkor@workerman.net",
166 | "homepage": "http://www.workerman.net",
167 | "role": "Developer"
168 | }
169 | ],
170 | "description": "An asynchronous event driven PHP framework for easily building fast, scalable network applications.",
171 | "homepage": "http://www.workerman.net",
172 | "keywords": [
173 | "asynchronous",
174 | "event-loop"
175 | ]
176 | },
177 | {
178 | "name": "topthink/framework",
179 | "version": "v5.0.3",
180 | "version_normalized": "5.0.3.0",
181 | "source": {
182 | "type": "git",
183 | "url": "https://github.com/top-think/framework.git",
184 | "reference": "fd30f090e40dc25a758d99029fa07f669f575580"
185 | },
186 | "dist": {
187 | "type": "zip",
188 | "url": "https://packagist.phpcomposer.com/files/top-think/framework/fd30f090e40dc25a758d99029fa07f669f575580.zip",
189 | "reference": "fd30f090e40dc25a758d99029fa07f669f575580",
190 | "shasum": ""
191 | },
192 | "require": {
193 | "php": ">=5.4.0",
194 | "topthink/think-installer": "~1.0"
195 | },
196 | "require-dev": {
197 | "johnkary/phpunit-speedtrap": "^1.0",
198 | "mikey179/vfsstream": "~1.6",
199 | "phpdocumentor/reflection-docblock": "^2.0",
200 | "phploc/phploc": "2.*",
201 | "phpunit/phpunit": "4.8.*",
202 | "sebastian/phpcpd": "2.*",
203 | "squizlabs/php_codesniffer": "2.*"
204 | },
205 | "time": "2016-11-11 09:22:23",
206 | "type": "think-framework",
207 | "installation-source": "dist",
208 | "autoload": {
209 | "psr-4": {
210 | "think\\": "library/think"
211 | }
212 | },
213 | "notification-url": "https://packagist.org/downloads/",
214 | "license": [
215 | "Apache-2.0"
216 | ],
217 | "authors": [
218 | {
219 | "name": "liu21st",
220 | "email": "liu21st@gmail.com"
221 | }
222 | ],
223 | "description": "the new thinkphp framework",
224 | "homepage": "http://thinkphp.cn/",
225 | "keywords": [
226 | "framework",
227 | "orm",
228 | "thinkphp"
229 | ]
230 | }
231 | ]
232 |
--------------------------------------------------------------------------------
/config/config.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 |
12 | return [
13 | // +----------------------------------------------------------------------
14 | // | 应用设置
15 | // +----------------------------------------------------------------------
16 |
17 | // 应用命名空间
18 | 'app_namespace' => 'app',
19 | // 应用调试模式
20 | 'app_debug' => true,
21 | // 应用Trace
22 | 'app_trace' => false,
23 | // 应用模式状态
24 | 'app_status' => '',
25 | // 是否支持多模块
26 | 'app_multi_module' => true,
27 | // 入口自动绑定模块
28 | 'auto_bind_module' => false,
29 | // 注册的根命名空间
30 | 'root_namespace' => [],
31 | // 扩展函数文件
32 | 'extra_file_list' => [THINK_PATH . 'helper' . EXT],
33 | // 默认输出类型
34 | 'default_return_type' => 'html',
35 | // 默认AJAX 数据返回格式,可选json xml ...
36 | 'default_ajax_return' => 'json',
37 | // 默认JSONP格式返回的处理方法
38 | 'default_jsonp_handler' => 'jsonpReturn',
39 | // 默认JSONP处理方法
40 | 'var_jsonp_handler' => 'callback',
41 | // 默认时区
42 | 'default_timezone' => 'PRC',
43 | // 是否开启多语言
44 | 'lang_switch_on' => false,
45 | // 默认全局过滤方法 用逗号分隔多个
46 | 'default_filter' => '',
47 | // 默认语言
48 | 'default_lang' => 'zh-cn',
49 | // 应用类库后缀
50 | 'class_suffix' => false,
51 | // 控制器类后缀
52 | 'controller_suffix' => false,
53 |
54 | // +----------------------------------------------------------------------
55 | // | 模块设置
56 | // +----------------------------------------------------------------------
57 |
58 | // 默认模块名
59 | 'default_module' => 'index',
60 | // 禁止访问模块
61 | 'deny_module_list' => ['common'],
62 | // 默认控制器名
63 | 'default_controller' => 'Index',
64 | // 默认操作名
65 | 'default_action' => 'index',
66 | // 默认验证器
67 | 'default_validate' => '',
68 | // 默认的空控制器名
69 | 'empty_controller' => 'Error',
70 | // 操作方法后缀
71 | 'action_suffix' => '',
72 | // 自动搜索控制器
73 | 'controller_auto_search' => false,
74 |
75 | // +----------------------------------------------------------------------
76 | // | URL设置
77 | // +----------------------------------------------------------------------
78 |
79 | // PATHINFO变量名 用于兼容模式
80 | 'var_pathinfo' => 's',
81 | // 兼容PATH_INFO获取
82 | 'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],
83 | // pathinfo分隔符
84 | 'pathinfo_depr' => '/',
85 | // URL伪静态后缀
86 | 'url_html_suffix' => 'html',
87 | // URL普通方式参数 用于自动生成
88 | 'url_common_param' => false,
89 | // URL参数方式 0 按名称成对解析 1 按顺序解析
90 | 'url_param_type' => 0,
91 | // 是否开启路由
92 | 'url_route_on' => true,
93 | // 路由使用完整匹配
94 | 'route_complete_match' => false,
95 | // 路由配置文件(支持配置多个)
96 | 'route_config_file' => ['route'],
97 | // 是否强制使用路由
98 | 'url_route_must' => false,
99 | // 域名部署
100 | 'url_domain_deploy' => false,
101 | // 域名根,如thinkphp.cn
102 | 'url_domain_root' => '',
103 | // 是否自动转换URL中的控制器和操作名
104 | 'url_convert' => true,
105 | // 默认的访问控制器层
106 | 'url_controller_layer' => 'controller',
107 | // 表单请求类型伪装变量
108 | 'var_method' => '_method',
109 | // 表单ajax伪装变量
110 | 'var_ajax' => '_ajax',
111 | // 表单pjax伪装变量
112 | 'var_pjax' => '_pjax',
113 | // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
114 | 'request_cache' => false,
115 | // 请求缓存有效期
116 | 'request_cache_expire' => null,
117 |
118 | // +----------------------------------------------------------------------
119 | // | 模板设置
120 | // +----------------------------------------------------------------------
121 |
122 | 'template' => [
123 | // 模板引擎类型 支持 php think 支持扩展
124 | 'type' => 'Think',
125 | // 模板路径
126 | 'view_path' => '',
127 | // 模板后缀
128 | 'view_suffix' => 'html',
129 | // 模板文件名分隔符
130 | 'view_depr' => DS,
131 | // 模板引擎普通标签开始标记
132 | 'tpl_begin' => '{',
133 | // 模板引擎普通标签结束标记
134 | 'tpl_end' => '}',
135 | // 标签库标签开始标记
136 | 'taglib_begin' => '{',
137 | // 标签库标签结束标记
138 | 'taglib_end' => '}',
139 | ],
140 |
141 | // 视图输出字符串内容替换
142 | 'view_replace_str' => [],
143 | // 默认跳转页面对应的模板文件
144 | 'dispatch_success_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl',
145 | 'dispatch_error_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl',
146 |
147 | // +----------------------------------------------------------------------
148 | // | 异常及错误设置
149 | // +----------------------------------------------------------------------
150 |
151 | // 异常页面的模板文件
152 | 'exception_tmpl' => THINK_PATH . 'tpl' . DS . 'think_exception.tpl',
153 |
154 | // 错误显示信息,非调试模式有效
155 | 'error_message' => '页面错误!请稍后再试~',
156 | // 显示错误信息
157 | 'show_error_msg' => false,
158 | // 异常处理handle类 留空使用 \think\exception\Handle
159 | 'exception_handle' => '',
160 |
161 | // +----------------------------------------------------------------------
162 | // | 日志设置
163 | // +----------------------------------------------------------------------
164 |
165 | 'log' => [
166 | // 日志记录方式,内置 file socket 支持扩展
167 | 'type' => 'File',
168 | // 日志保存目录
169 | 'path' => LOG_PATH,
170 | // 日志记录级别
171 | 'level' => [],
172 | ],
173 |
174 | // +----------------------------------------------------------------------
175 | // | Trace设置 开启 app_trace 后 有效
176 | // +----------------------------------------------------------------------
177 | 'trace' => [
178 | // 内置Html Console 支持扩展
179 | 'type' => 'Html',
180 | ],
181 |
182 | // +----------------------------------------------------------------------
183 | // | 缓存设置
184 | // +----------------------------------------------------------------------
185 |
186 | 'cache' => [
187 | // 驱动方式
188 | 'type' => 'File',
189 | // 缓存保存目录
190 | 'path' => CACHE_PATH,
191 | // 缓存前缀
192 | 'prefix' => '',
193 | // 缓存有效期 0表示永久缓存
194 | 'expire' => 0,
195 | ],
196 |
197 | // +----------------------------------------------------------------------
198 | // | 会话设置
199 | // +----------------------------------------------------------------------
200 |
201 | 'session' => [
202 | 'id' => '',
203 | // SESSION_ID的提交变量,解决flash上传跨域
204 | 'var_session_id' => '',
205 | // SESSION 前缀
206 | 'prefix' => 'think',
207 | // 驱动方式 支持redis memcache memcached
208 | 'type' => '',
209 | // 是否自动开启 SESSION
210 | 'auto_start' => true,
211 | ],
212 |
213 | // +----------------------------------------------------------------------
214 | // | Cookie设置
215 | // +----------------------------------------------------------------------
216 | 'cookie' => [
217 | // cookie 名称前缀
218 | 'prefix' => '',
219 | // cookie 保存时间
220 | 'expire' => 0,
221 | // cookie 保存路径
222 | 'path' => '/',
223 | // cookie 有效域名
224 | 'domain' => '',
225 | // cookie 启用安全传输
226 | 'secure' => false,
227 | // httponly设置
228 | 'httponly' => '',
229 | // 是否使用 setcookie
230 | 'setcookie' => true,
231 | ],
232 |
233 | //分页配置
234 | 'paginate' => [
235 | 'type' => 'bootstrap',
236 | 'var_page' => 'page',
237 | 'list_rows' => 15,
238 | ],
239 | ];
240 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman/Events/Select.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Events;
15 |
16 | /**
17 | * select eventloop
18 | */
19 | class Select implements EventInterface
20 | {
21 | /**
22 | * All listeners for read/write event.
23 | *
24 | * @var array
25 | */
26 | public $_allEvents = array();
27 |
28 | /**
29 | * Event listeners of signal.
30 | *
31 | * @var array
32 | */
33 | public $_signalEvents = array();
34 |
35 | /**
36 | * Fds waiting for read event.
37 | *
38 | * @var array
39 | */
40 | protected $_readFds = array();
41 |
42 | /**
43 | * Fds waiting for write event.
44 | *
45 | * @var array
46 | */
47 | protected $_writeFds = array();
48 |
49 | /**
50 | * Timer scheduler.
51 | * {['data':timer_id, 'priority':run_timestamp], ..}
52 | *
53 | * @var \SplPriorityQueue
54 | */
55 | protected $_scheduler = null;
56 |
57 | /**
58 | * All timer event listeners.
59 | * [[func, args, flag, timer_interval], ..]
60 | *
61 | * @var array
62 | */
63 | protected $_task = array();
64 |
65 | /**
66 | * Timer id.
67 | *
68 | * @var int
69 | */
70 | protected $_timerId = 1;
71 |
72 | /**
73 | * Select timeout.
74 | *
75 | * @var int
76 | */
77 | protected $_selectTimeout = 100000000;
78 |
79 | /**
80 | * Paired socket channels
81 | *
82 | * @var array
83 | */
84 | protected $channel = array();
85 |
86 | /**
87 | * Construct.
88 | */
89 | public function __construct()
90 | {
91 | // Create a pipeline and put into the collection of the read to read the descriptor to avoid empty polling.
92 | $this->channel = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
93 | if ($this->channel) {
94 | stream_set_blocking($this->channel[0], 0);
95 | $this->_readFds[0] = $this->channel[0];
96 | }
97 | // Init SplPriorityQueue.
98 | $this->_scheduler = new \SplPriorityQueue();
99 | $this->_scheduler->setExtractFlags(\SplPriorityQueue::EXTR_BOTH);
100 | }
101 |
102 | /**
103 | * {@inheritdoc}
104 | */
105 | public function add($fd, $flag, $func, $args = array())
106 | {
107 | switch ($flag) {
108 | case self::EV_READ:
109 | $fd_key = (int)$fd;
110 | $this->_allEvents[$fd_key][$flag] = array($func, $fd);
111 | $this->_readFds[$fd_key] = $fd;
112 | break;
113 | case self::EV_WRITE:
114 | $fd_key = (int)$fd;
115 | $this->_allEvents[$fd_key][$flag] = array($func, $fd);
116 | $this->_writeFds[$fd_key] = $fd;
117 | break;
118 | case self::EV_SIGNAL:
119 | $fd_key = (int)$fd;
120 | $this->_signalEvents[$fd_key][$flag] = array($func, $fd);
121 | pcntl_signal($fd, array($this, 'signalHandler'));
122 | break;
123 | case self::EV_TIMER:
124 | case self::EV_TIMER_ONCE:
125 | $run_time = microtime(true) + $fd;
126 | $this->_scheduler->insert($this->_timerId, -$run_time);
127 | $this->_task[$this->_timerId] = array($func, (array)$args, $flag, $fd);
128 | $this->tick();
129 | return $this->_timerId++;
130 | }
131 |
132 | return true;
133 | }
134 |
135 | /**
136 | * Signal handler.
137 | *
138 | * @param int $signal
139 | */
140 | public function signalHandler($signal)
141 | {
142 | call_user_func_array($this->_signalEvents[$signal][self::EV_SIGNAL][0], array($signal));
143 | }
144 |
145 | /**
146 | * {@inheritdoc}
147 | */
148 | public function del($fd, $flag)
149 | {
150 | $fd_key = (int)$fd;
151 | switch ($flag) {
152 | case self::EV_READ:
153 | unset($this->_allEvents[$fd_key][$flag], $this->_readFds[$fd_key]);
154 | if (empty($this->_allEvents[$fd_key])) {
155 | unset($this->_allEvents[$fd_key]);
156 | }
157 | return true;
158 | case self::EV_WRITE:
159 | unset($this->_allEvents[$fd_key][$flag], $this->_writeFds[$fd_key]);
160 | if (empty($this->_allEvents[$fd_key])) {
161 | unset($this->_allEvents[$fd_key]);
162 | }
163 | return true;
164 | case self::EV_SIGNAL:
165 | unset($this->_signalEvents[$fd_key]);
166 | pcntl_signal($fd, SIG_IGN);
167 | break;
168 | case self::EV_TIMER:
169 | case self::EV_TIMER_ONCE;
170 | unset($this->_task[$fd_key]);
171 | return true;
172 | }
173 | return false;
174 | }
175 |
176 | /**
177 | * Tick for timer.
178 | *
179 | * @return void
180 | */
181 | protected function tick()
182 | {
183 | while (!$this->_scheduler->isEmpty()) {
184 | $scheduler_data = $this->_scheduler->top();
185 | $timer_id = $scheduler_data['data'];
186 | $next_run_time = -$scheduler_data['priority'];
187 | $time_now = microtime(true);
188 | $this->_selectTimeout = ($next_run_time - $time_now) * 1000000;
189 | if ($this->_selectTimeout <= 0) {
190 | $this->_scheduler->extract();
191 |
192 | if (!isset($this->_task[$timer_id])) {
193 | continue;
194 | }
195 |
196 | // [func, args, flag, timer_interval]
197 | $task_data = $this->_task[$timer_id];
198 | if ($task_data[2] === self::EV_TIMER) {
199 | $next_run_time = $time_now + $task_data[3];
200 | $this->_scheduler->insert($timer_id, -$next_run_time);
201 | }
202 | call_user_func_array($task_data[0], $task_data[1]);
203 | if (isset($this->_task[$timer_id]) && $task_data[2] === self::EV_TIMER_ONCE) {
204 | $this->del($timer_id, self::EV_TIMER_ONCE);
205 | }
206 | continue;
207 | }
208 | return;
209 | }
210 | $this->_selectTimeout = 100000000;
211 | }
212 |
213 | /**
214 | * {@inheritdoc}
215 | */
216 | public function clearAllTimer()
217 | {
218 | $this->_scheduler = new \SplPriorityQueue();
219 | $this->_scheduler->setExtractFlags(\SplPriorityQueue::EXTR_BOTH);
220 | $this->_task = array();
221 | }
222 |
223 | /**
224 | * {@inheritdoc}
225 | */
226 | public function loop()
227 | {
228 | $e = null;
229 | while (1) {
230 | // Calls signal handlers for pending signals
231 | pcntl_signal_dispatch();
232 |
233 | $read = $this->_readFds;
234 | $write = $this->_writeFds;
235 | // Waiting read/write/signal/timeout events.
236 | $ret = @stream_select($read, $write, $e, 0, $this->_selectTimeout);
237 |
238 | if (!$this->_scheduler->isEmpty()) {
239 | $this->tick();
240 | }
241 |
242 | if (!$ret) {
243 | continue;
244 | }
245 |
246 | foreach ($read as $fd) {
247 | $fd_key = (int)$fd;
248 | if (isset($this->_allEvents[$fd_key][self::EV_READ])) {
249 | call_user_func_array($this->_allEvents[$fd_key][self::EV_READ][0],
250 | array($this->_allEvents[$fd_key][self::EV_READ][1]));
251 | }
252 | }
253 |
254 | foreach ($write as $fd) {
255 | $fd_key = (int)$fd;
256 | if (isset($this->_allEvents[$fd_key][self::EV_WRITE])) {
257 | call_user_func_array($this->_allEvents[$fd_key][self::EV_WRITE][0],
258 | array($this->_allEvents[$fd_key][self::EV_WRITE][1]));
259 | }
260 | }
261 | }
262 | }
263 | }
264 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman/Connection/AsyncTcpConnection.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Connection;
15 |
16 | use Workerman\Events\EventInterface;
17 | use Workerman\Worker;
18 | use Exception;
19 |
20 | /**
21 | * AsyncTcpConnection.
22 | */
23 | class AsyncTcpConnection extends TcpConnection
24 | {
25 | /**
26 | * Emitted when socket connection is successfully established.
27 | *
28 | * @var callback
29 | */
30 | public $onConnect = null;
31 |
32 | /**
33 | * Transport layer protocol.
34 | *
35 | * @var string
36 | */
37 | public $transport = 'tcp';
38 |
39 | /**
40 | * Status.
41 | *
42 | * @var int
43 | */
44 | protected $_status = self::STATUS_INITIAL;
45 |
46 | /**
47 | * Remote host.
48 | *
49 | * @var string
50 | */
51 | protected $_remoteHost = '';
52 |
53 | /**
54 | * Connect start time.
55 | *
56 | * @var string
57 | */
58 | protected $_connectStartTime = 0;
59 |
60 | /**
61 | * Remote URI.
62 | *
63 | * @var string
64 | */
65 | protected $_remoteURI = '';
66 |
67 |
68 | /**
69 | * PHP built-in protocols.
70 | *
71 | * @var array
72 | */
73 | protected static $_builtinTransports = array(
74 | 'tcp' => 'tcp',
75 | 'udp' => 'udp',
76 | 'unix' => 'unix',
77 | 'ssl' => 'ssl',
78 | 'sslv2' => 'sslv2',
79 | 'sslv3' => 'sslv3',
80 | 'tls' => 'tls'
81 | );
82 |
83 | /**
84 | * Construct.
85 | *
86 | * @param string $remote_address
87 | * @throws Exception
88 | */
89 | public function __construct($remote_address)
90 | {
91 | $address_info = parse_url($remote_address);
92 | if (!$address_info) {
93 | echo new \Exception('bad remote_address');
94 | $this->_remoteAddress = $remote_address;
95 | } else {
96 | if (!isset($address_info['port'])) {
97 | $address_info['port'] = 80;
98 | }
99 | if (!isset($address_info['path'])) {
100 | $address_info['path'] = '/';
101 | }
102 | if (!isset($address_info['query'])) {
103 | $address_info['query'] = '';
104 | } else {
105 | $address_info['query'] = '?' . $address_info['query'];
106 | }
107 | $this->_remoteAddress = "{$address_info['host']}:{$address_info['port']}";
108 | $this->_remoteHost = $address_info['host'];
109 | $this->_remoteURI = "{$address_info['path']}{$address_info['query']}";
110 | $scheme = isset($address_info['scheme']) ? $address_info['scheme'] : 'tcp';
111 | }
112 |
113 | $this->id = self::$_idRecorder++;
114 | // Check application layer protocol class.
115 | if (!isset(self::$_builtinTransports[$scheme])) {
116 | $scheme = ucfirst($scheme);
117 | $this->protocol = '\\Protocols\\' . $scheme;
118 | if (!class_exists($this->protocol)) {
119 | $this->protocol = "\\Workerman\\Protocols\\$scheme";
120 | if (!class_exists($this->protocol)) {
121 | throw new Exception("class \\Protocols\\$scheme not exist");
122 | }
123 | }
124 | } else {
125 | $this->transport = self::$_builtinTransports[$scheme];
126 | }
127 |
128 | // For statistics.
129 | self::$statistics['connection_count']++;
130 | $this->maxSendBufferSize = self::$defaultMaxSendBufferSize;
131 | }
132 |
133 | /**
134 | * Do connect.
135 | *
136 | * @return void
137 | */
138 | public function connect()
139 | {
140 | if ($this->_status !== self::STATUS_INITIAL && $this->_status !== self::STATUS_CLOSING && $this->_status !== self::STATUS_CLOSED) {
141 | return;
142 | }
143 | $this->_status = self::STATUS_CONNECTING;
144 | $this->_connectStartTime = microtime(true);
145 | // Open socket connection asynchronously.
146 | $this->_socket = stream_socket_client("{$this->transport}://{$this->_remoteAddress}", $errno, $errstr, 0,
147 | STREAM_CLIENT_ASYNC_CONNECT);
148 | // If failed attempt to emit onError callback.
149 | if (!$this->_socket) {
150 | $this->emitError(WORKERMAN_CONNECT_FAIL, $errstr);
151 | if ($this->_status === self::STATUS_CLOSING) {
152 | $this->destroy();
153 | }
154 | if ($this->_status === self::STATUS_CLOSED) {
155 | $this->onConnect = null;
156 | }
157 | return;
158 | }
159 | // Add socket to global event loop waiting connection is successfully established or faild.
160 | Worker::$globalEvent->add($this->_socket, EventInterface::EV_WRITE, array($this, 'checkConnection'));
161 | }
162 |
163 | /**
164 | * Get remote address.
165 | *
166 | * @return string
167 | */
168 | public function getRemoteHost()
169 | {
170 | return $this->_remoteHost;
171 | }
172 |
173 | /**
174 | * Get remote URI.
175 | *
176 | * @return string
177 | */
178 | public function getRemoteURI()
179 | {
180 | return $this->_remoteURI;
181 | }
182 |
183 | /**
184 | * Try to emit onError callback.
185 | *
186 | * @param int $code
187 | * @param string $msg
188 | * @return void
189 | */
190 | protected function emitError($code, $msg)
191 | {
192 | $this->_status = self::STATUS_CLOSING;
193 | if ($this->onError) {
194 | try {
195 | call_user_func($this->onError, $this, $code, $msg);
196 | } catch (\Exception $e) {
197 | Worker::log($e);
198 | exit(250);
199 | } catch (\Error $e) {
200 | Worker::log($e);
201 | exit(250);
202 | }
203 | }
204 | }
205 |
206 | /**
207 | * Check connection is successfully established or faild.
208 | *
209 | * @param resource $socket
210 | * @return void
211 | */
212 | public function checkConnection($socket)
213 | {
214 | // Check socket state.
215 | if ($address = stream_socket_get_name($socket, true)) {
216 | // Remove write listener.
217 | Worker::$globalEvent->del($socket, EventInterface::EV_WRITE);
218 | // Nonblocking.
219 | stream_set_blocking($socket, 0);
220 | // Compatible with hhvm
221 | if (function_exists('stream_set_read_buffer')) {
222 | stream_set_read_buffer($socket, 0);
223 | }
224 | // Try to open keepalive for tcp and disable Nagle algorithm.
225 | if (function_exists('socket_import_stream') && $this->transport === 'tcp') {
226 | $raw_socket = socket_import_stream($socket);
227 | socket_set_option($raw_socket, SOL_SOCKET, SO_KEEPALIVE, 1);
228 | socket_set_option($raw_socket, SOL_TCP, TCP_NODELAY, 1);
229 | }
230 | // Register a listener waiting read event.
231 | Worker::$globalEvent->add($socket, EventInterface::EV_READ, array($this, 'baseRead'));
232 | // There are some data waiting to send.
233 | if ($this->_sendBuffer) {
234 | Worker::$globalEvent->add($socket, EventInterface::EV_WRITE, array($this, 'baseWrite'));
235 | }
236 | $this->_status = self::STATUS_ESTABLISH;
237 | $this->_remoteAddress = $address;
238 |
239 | // Try to emit onConnect callback.
240 | if ($this->onConnect) {
241 | try {
242 | call_user_func($this->onConnect, $this);
243 | } catch (\Exception $e) {
244 | Worker::log($e);
245 | exit(250);
246 | } catch (\Error $e) {
247 | Worker::log($e);
248 | exit(250);
249 | }
250 | }
251 | // Try to emit protocol::onConnect
252 | if (method_exists($this->protocol, 'onConnect')) {
253 | try {
254 | call_user_func(array($this->protocol, 'onConnect'), $this);
255 | } catch (\Exception $e) {
256 | Worker::log($e);
257 | exit(250);
258 | } catch (\Error $e) {
259 | Worker::log($e);
260 | exit(250);
261 | }
262 | }
263 | } else {
264 | // Connection failed.
265 | $this->emitError(WORKERMAN_CONNECT_FAIL, 'connect ' . $this->_remoteAddress . ' fail after ' . round(microtime(true) - $this->_connectStartTime, 4) . ' seconds');
266 | if ($this->_status === self::STATUS_CLOSING) {
267 | $this->destroy();
268 | }
269 | if ($this->_status === self::STATUS_CLOSED) {
270 | $this->onConnect = null;
271 | }
272 | }
273 | }
274 | }
275 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman-for-win/Events/Select.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Events;
15 |
16 | class Select implements EventInterface
17 | {
18 | /**
19 | * 所有的事件
20 | * @var array
21 | */
22 | public $_allEvents = array();
23 |
24 | /**
25 | * 所有信号事件
26 | * @var array
27 | */
28 | public $_signalEvents = array();
29 |
30 | /**
31 | * 监听这些描述符的读事件
32 | * @var array
33 | */
34 | protected $_readFds = array();
35 |
36 | /**
37 | * 监听这些描述符的写事件
38 | * @var array
39 | */
40 | protected $_writeFds = array();
41 |
42 | /**
43 | * 监听这些描述符的带外事件
44 | * @var array
45 | */
46 | protected $_exceptFds = array();
47 |
48 | /**
49 | * 任务调度器,最大堆
50 | * {['data':timer_id, 'priority':run_timestamp], ..}
51 | * @var SplPriorityQueue
52 | */
53 | protected $_scheduler = null;
54 |
55 | /**
56 | * 定时任务
57 | * [[func, args, flag, timer_interval], ..]
58 | * @var array
59 | */
60 | protected $_task = array();
61 |
62 | /**
63 | * 定时器id
64 | * @var int
65 | */
66 | protected $_timerId = 1;
67 |
68 | /**
69 | * select超时时间,单位:微秒
70 | * @var int
71 | */
72 | protected $_selectTimeout = 100000000;
73 |
74 | /**
75 | * 构造函数
76 | * @return void
77 | */
78 | public function __construct()
79 | {
80 | // 创建一个管道,放入监听读的描述符集合中,避免空轮询
81 | $this->channel = stream_socket_pair(STREAM_PF_INET, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
82 | if($this->channel)
83 | {
84 | stream_set_blocking($this->channel[0], 0);
85 | $this->_readFds[0] = $this->channel[0];
86 | }
87 | // 初始化优先队列(最大堆)
88 | $this->_scheduler = new \SplPriorityQueue();
89 | $this->_scheduler->setExtractFlags(\SplPriorityQueue::EXTR_BOTH);
90 | }
91 |
92 | /**
93 | * 添加事件及处理函数
94 | * @see Events\EventInterface::add()
95 | */
96 | public function add($fd, $flag, $func, $args = array())
97 | {
98 | switch ($flag)
99 | {
100 | case self::EV_READ:
101 | $fd_key = (int)$fd;
102 | $this->_allEvents[$fd_key][$flag] = array($func, $fd);
103 | $this->_readFds[$fd_key] = $fd;
104 | break;
105 | case self::EV_WRITE:
106 | $fd_key = (int)$fd;
107 | $this->_allEvents[$fd_key][$flag] = array($func, $fd);
108 | $this->_writeFds[$fd_key] = $fd;
109 | break;
110 | case self::EV_EXCEPT:
111 | $fd_key = (int)$fd;
112 | $this->_allEvents[$fd_key][$flag] = array($func, $fd);
113 | $this->_exceptFds[$fd_key] = $fd;
114 | break;
115 | case self::EV_SIGNAL:
116 | throw new \Exception("not support EV_SIGNAL on Windows");
117 | break;
118 | case self::EV_TIMER:
119 | case self::EV_TIMER_ONCE:
120 | // $fd 为 定时的时间间隔,单位为秒,支持小数,能精确到0.001秒
121 | $run_time = microtime(true)+$fd;
122 | $this->_scheduler->insert($this->_timerId, -$run_time);
123 | $this->_task[$this->_timerId] = array($func, (array)$args, $flag, $fd);
124 | $this->tick();
125 | return $this->_timerId++;
126 | }
127 |
128 | return true;
129 | }
130 |
131 | /**
132 | * 信号处理函数
133 | * @param int $signal
134 | */
135 | public function signalHandler($signal)
136 | {
137 | call_user_func_array($this->_signalEvents[$signal][self::EV_SIGNAL][0], array($signal));
138 | }
139 |
140 | /**
141 | * 删除某个描述符的某类事件的监听
142 | * @see Events\EventInterface::del()
143 | */
144 | public function del($fd ,$flag)
145 | {
146 | $fd_key = (int)$fd;
147 | switch ($flag)
148 | {
149 | case self::EV_READ:
150 | unset($this->_allEvents[$fd_key][$flag], $this->_readFds[$fd_key]);
151 | if(empty($this->_allEvents[$fd_key]))
152 | {
153 | unset($this->_allEvents[$fd_key]);
154 | }
155 | return true;
156 | case self::EV_WRITE:
157 | unset($this->_allEvents[$fd_key][$flag], $this->_writeFds[$fd_key]);
158 | if(empty($this->_allEvents[$fd_key]))
159 | {
160 | unset($this->_allEvents[$fd_key]);
161 | }
162 | return true;
163 | case self::EV_EXCEPT:
164 | unset($this->_allEvents[$fd_key][$flag], $this->_exceptFds[$fd_key]);
165 | if(empty($this->_allEvents[$fd_key]))
166 | {
167 | unset($this->_allEvents[$fd_key]);
168 | }
169 | return true;
170 | case self::EV_SIGNAL:
171 | break;
172 | case self::EV_TIMER:
173 | case self::EV_TIMER_ONCE;
174 | // $fd_key为要删除的定时器id,即timerId
175 | unset($this->_task[$fd_key]);
176 | return true;
177 | }
178 | return false;;
179 | }
180 |
181 | /**
182 | * 检查是否有可执行的定时任务,有的话执行
183 | * @return void
184 | */
185 | protected function tick()
186 | {
187 | while(!$this->_scheduler->isEmpty())
188 | {
189 | $scheduler_data = $this->_scheduler->top();
190 | $timer_id = $scheduler_data['data'];
191 | $next_run_time = -$scheduler_data['priority'];
192 | $time_now = microtime(true);
193 | $this->_selectTimeout = ($next_run_time - $time_now) * 1000000;
194 | if ($this->_selectTimeout <= 0) {
195 | $this->_scheduler->extract();
196 | if (!isset($this->_task[$timer_id])) {
197 | continue;
198 | }
199 | // [func, args, flag, timer_interval]
200 | $task_data = $this->_task[$timer_id];
201 | if ($task_data[2] === self::EV_TIMER) {
202 | $next_run_time = $time_now + $task_data[3];
203 | $this->_scheduler->insert($timer_id, -$next_run_time);
204 | }
205 | call_user_func_array($task_data[0], $task_data[1]);
206 | if (isset($this->_task[$timer_id]) && $task_data[2] === self::EV_TIMER_ONCE) {
207 | $this->del($timer_id, self::EV_TIMER_ONCE);
208 | }
209 | continue;
210 | }
211 | return;
212 | }
213 | $this->_selectTimeout = 100000000;
214 | }
215 |
216 | /**
217 | * 删除所有定时器
218 | * @return void
219 | */
220 | public function clearAllTimer()
221 | {
222 | $this->_scheduler = new \SplPriorityQueue();
223 | $this->_scheduler->setExtractFlags(\SplPriorityQueue::EXTR_BOTH);
224 | $this->_task = array();
225 | }
226 |
227 | /**
228 | * 主循环
229 | * @see Events\EventInterface::loop()
230 | */
231 | public function loop()
232 | {
233 | $e = null;
234 | while (1)
235 | {
236 | $read = $this->_readFds;
237 | $write = $this->_writeFds;
238 | $except = $this->_writeFds;
239 |
240 | // 等待可读或者可写事件
241 | stream_select($read, $write, $except, 0, (int)($this->_selectTimeout.''));
242 |
243 | // 尝试执行定时任务
244 | if(!$this->_scheduler->isEmpty())
245 | {
246 | $this->tick();
247 | }
248 |
249 | // 这些描述符可读,执行对应描述符的读回调函数
250 | if($read)
251 | {
252 | foreach($read as $fd)
253 | {
254 | $fd_key = (int) $fd;
255 | if(isset($this->_allEvents[$fd_key][self::EV_READ]))
256 | {
257 | call_user_func_array($this->_allEvents[$fd_key][self::EV_READ][0], array($this->_allEvents[$fd_key][self::EV_READ][1]));
258 | }
259 | }
260 | }
261 |
262 | // 这些描述符可写,执行对应描述符的写回调函数
263 | if($write)
264 | {
265 | foreach($write as $fd)
266 | {
267 | $fd_key = (int) $fd;
268 | if(isset($this->_allEvents[$fd_key][self::EV_WRITE]))
269 | {
270 | call_user_func_array($this->_allEvents[$fd_key][self::EV_WRITE][0], array($this->_allEvents[$fd_key][self::EV_WRITE][1]));
271 | }
272 | }
273 | }
274 |
275 | // 这些描述符可写,执行对应描述符的写回调函数
276 | if($except)
277 | {
278 | foreach($except as $fd)
279 | {
280 | $fd_key = (int) $fd;
281 | if(isset($this->_allEvents[$fd_key][self::EV_EXCEPT]))
282 | {
283 | call_user_func_array($this->_allEvents[$fd_key][self::EV_EXCEPT][0], array($this->_allEvents[$fd_key][self::EV_EXCEPT][1]));
284 | }
285 | }
286 | }
287 | }
288 | }
289 | }
290 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman-for-win/WebServer.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman;
15 |
16 | use Workerman\Protocols\Http;
17 | use Workerman\Protocols\HttpCache;
18 |
19 | /**
20 | * WebServer.
21 | */
22 | class WebServer extends Worker
23 | {
24 | /**
25 | * Mime.
26 | *
27 | * @var string
28 | */
29 | protected static $defaultMimeType = 'text/html; charset=utf-8';
30 |
31 | /**
32 | * Virtual host to path mapping.
33 | *
34 | * @var array ['workerman.net'=>'/home', 'www.workerman.net'=>'home/www']
35 | */
36 | protected $serverRoot = array();
37 |
38 | /**
39 | * Mime mapping.
40 | *
41 | * @var array
42 | */
43 | protected static $mimeTypeMap = array();
44 |
45 |
46 | /**
47 | * Used to save user OnWorkerStart callback settings.
48 | *
49 | * @var callback
50 | */
51 | protected $_onWorkerStart = null;
52 |
53 | /**
54 | * Add virtual host.
55 | *
56 | * @param string $domain
57 | * @param string $root_path
58 | * @return void
59 | */
60 | public function addRoot($domain, $root_path)
61 | {
62 | $this->serverRoot[$domain] = $root_path;
63 | }
64 |
65 | /**
66 | * Construct.
67 | *
68 | * @param string $socket_name
69 | * @param array $context_option
70 | */
71 | public function __construct($socket_name, $context_option = array())
72 | {
73 | list(, $address) = explode(':', $socket_name, 2);
74 | parent::__construct('http:' . $address, $context_option);
75 | $this->name = 'WebServer';
76 | }
77 |
78 | /**
79 | * Run webserver instance.
80 | *
81 | * @see Workerman.Worker::run()
82 | */
83 | public function run()
84 | {
85 | $this->_onWorkerStart = $this->onWorkerStart;
86 | $this->onWorkerStart = array($this, 'onWorkerStart');
87 | $this->onMessage = array($this, 'onMessage');
88 | parent::run();
89 | }
90 |
91 | /**
92 | * Emit when process start.
93 | *
94 | * @throws \Exception
95 | */
96 | public function onWorkerStart()
97 | {
98 | if (empty($this->serverRoot)) {
99 | throw new \Exception('server root not set, please use WebServer::addRoot($domain, $root_path) to set server root path');
100 | }
101 | // Init HttpCache.
102 | HttpCache::init();
103 | // Init mimeMap.
104 | $this->initMimeTypeMap();
105 |
106 | // Try to emit onWorkerStart callback.
107 | if ($this->_onWorkerStart) {
108 | try {
109 | call_user_func($this->_onWorkerStart, $this);
110 | } catch (\Exception $e) {
111 | self::log($e);
112 | exit(250);
113 | } catch (\Error $e) {
114 | self::log($e);
115 | exit(250);
116 | }
117 | }
118 | }
119 |
120 | /**
121 | * Init mime map.
122 | *
123 | * @return void
124 | */
125 | public function initMimeTypeMap()
126 | {
127 | $mime_file = Http::getMimeTypesFile();
128 | if (!is_file($mime_file)) {
129 | $this->log("$mime_file mime.type file not fond");
130 | return;
131 | }
132 | $items = file($mime_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
133 | if (!is_array($items)) {
134 | $this->log("get $mime_file mime.type content fail");
135 | return;
136 | }
137 | foreach ($items as $content) {
138 | if (preg_match("/\s*(\S+)\s+(\S.+)/", $content, $match)) {
139 | $mime_type = $match[1];
140 | $workerman_file_extension_var = $match[2];
141 | $workerman_file_extension_array = explode(' ', substr($workerman_file_extension_var, 0, -1));
142 | foreach ($workerman_file_extension_array as $workerman_file_extension) {
143 | self::$mimeTypeMap[$workerman_file_extension] = $mime_type;
144 | }
145 | }
146 | }
147 | }
148 |
149 | /**
150 | * Emit when http message coming.
151 | *
152 | * @param Connection\TcpConnection $connection
153 | * @return void
154 | */
155 | public function onMessage($connection)
156 | {
157 | // REQUEST_URI.
158 | $workerman_url_info = parse_url($_SERVER['REQUEST_URI']);
159 | if (!$workerman_url_info) {
160 | Http::header('HTTP/1.1 400 Bad Request');
161 | $connection->close('400 Bad Request
');
162 | return;
163 | }
164 |
165 | $workerman_path = isset($workerman_url_info['path']) ? $workerman_url_info['path'] : '/';
166 |
167 | $workerman_path_info = pathinfo($workerman_path);
168 | $workerman_file_extension = isset($workerman_path_info['extension']) ? $workerman_path_info['extension'] : '';
169 | if ($workerman_file_extension === '') {
170 | $workerman_path = ($len = strlen($workerman_path)) && $workerman_path[$len - 1] === '/' ? $workerman_path . 'index.php' : $workerman_path . '/index.php';
171 | $workerman_file_extension = 'php';
172 | }
173 |
174 | $workerman_root_dir = isset($this->serverRoot[$_SERVER['SERVER_NAME']]) ? $this->serverRoot[$_SERVER['SERVER_NAME']] : current($this->serverRoot);
175 |
176 | $workerman_file = "$workerman_root_dir/$workerman_path";
177 |
178 | if ($workerman_file_extension === 'php' && !is_file($workerman_file)) {
179 | $workerman_file = "$workerman_root_dir/index.php";
180 | if (!is_file($workerman_file)) {
181 | $workerman_file = "$workerman_root_dir/index.html";
182 | $workerman_file_extension = 'html';
183 | }
184 | }
185 |
186 | // File exsits.
187 | if (is_file($workerman_file)) {
188 | // Security check.
189 | if ((!($workerman_request_realpath = realpath($workerman_file)) || !($workerman_root_dir_realpath = realpath($workerman_root_dir))) || 0 !== strpos($workerman_request_realpath,
190 | $workerman_root_dir_realpath)
191 | ) {
192 | Http::header('HTTP/1.1 400 Bad Request');
193 | $connection->close('400 Bad Request
');
194 | return;
195 | }
196 |
197 | $workerman_file = realpath($workerman_file);
198 |
199 | // Request php file.
200 | if ($workerman_file_extension === 'php') {
201 | $workerman_cwd = getcwd();
202 | chdir($workerman_root_dir);
203 | ini_set('display_errors', 'off');
204 | ob_start();
205 | // Try to include php file.
206 | try {
207 | // $_SERVER.
208 | $_SERVER['REMOTE_ADDR'] = $connection->getRemoteIp();
209 | $_SERVER['REMOTE_PORT'] = $connection->getRemotePort();
210 | include $workerman_file;
211 | } catch (\Exception $e) {
212 | // Jump_exit?
213 | if ($e->getMessage() != 'jump_exit') {
214 | echo $e;
215 | }
216 | }
217 | $content = ob_get_clean();
218 | ini_set('display_errors', 'on');
219 | $connection->close($content);
220 | chdir($workerman_cwd);
221 | return;
222 | }
223 |
224 | // Send file to client.
225 | return self::sendFile($connection, $workerman_file);
226 | } else {
227 | // 404
228 | Http::header("HTTP/1.1 404 Not Found");
229 | $connection->close('404 File not found404 Not Found
');
230 | return;
231 | }
232 | }
233 |
234 | public static function sendFile($connection, $file_name)
235 | {
236 | // Check 304.
237 | $info = stat($file_name);
238 | $modified_time = $info ? date('D, d M Y H:i:s', $info['mtime']) . ' GMT' : '';
239 | if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $info) {
240 | // Http 304.
241 | if ($modified_time === $_SERVER['HTTP_IF_MODIFIED_SINCE']) {
242 | // 304
243 | Http::header('HTTP/1.1 304 Not Modified');
244 | // Send nothing but http headers..
245 | $connection->close('');
246 | return;
247 | }
248 | }
249 |
250 | // Http header.
251 | if ($modified_time) {
252 | $modified_time = "Last-Modified: $modified_time\r\n";
253 | }
254 | $file_size = filesize($file_name);
255 | $extension = pathinfo($file_name, PATHINFO_EXTENSION);
256 | $content_type = isset(self::$mimeTypeMap[$extension]) ? self::$mimeTypeMap[$extension] : self::$defaultMimeType;
257 | $header = "HTTP/1.1 200 OK\r\n";
258 | $header .= "Content-Type: $content_type\r\n";
259 | $header .= "Connection: keep-alive\r\n";
260 | $header .= $modified_time;
261 | $header .= "Content-Length: $file_size\r\n\r\n";
262 | $trunk_limit_size = 1024*1024;
263 | if ($file_size < $trunk_limit_size) {
264 | return $connection->send($header.file_get_contents($file_name), true);
265 | }
266 | $connection->send($header, true);
267 |
268 | // Read file content from disk piece by piece and send to client.
269 | $connection->fileHandler = fopen($file_name, 'r');
270 | $do_write = function()use($connection)
271 | {
272 | // Send buffer not full.
273 | while(empty($connection->bufferFull))
274 | {
275 | // Read from disk.
276 | $buffer = fread($connection->fileHandler, 8192);
277 | // Read eof.
278 | if($buffer === '' || $buffer === false)
279 | {
280 | return;
281 | }
282 | $connection->send($buffer, true);
283 | }
284 | };
285 | // Send buffer full.
286 | $connection->onBufferFull = function($connection)
287 | {
288 | $connection->bufferFull = true;
289 | };
290 | // Send buffer drain.
291 | $connection->onBufferDrain = function($connection)use($do_write)
292 | {
293 | $connection->bufferFull = false;
294 | $do_write();
295 | };
296 | $do_write();
297 | }
298 | }
299 |
--------------------------------------------------------------------------------
/vendor/workerman/workerman/WebServer.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman;
15 |
16 | use Workerman\Protocols\Http;
17 | use Workerman\Protocols\HttpCache;
18 |
19 | /**
20 | * WebServer.
21 | */
22 | class WebServer extends Worker
23 | {
24 | /**
25 | * Virtual host to path mapping.
26 | *
27 | * @var array ['workerman.net'=>'/home', 'www.workerman.net'=>'home/www']
28 | */
29 | protected $serverRoot = array();
30 |
31 | /**
32 | * Mime mapping.
33 | *
34 | * @var array
35 | */
36 | protected static $mimeTypeMap = array();
37 |
38 |
39 | /**
40 | * Used to save user OnWorkerStart callback settings.
41 | *
42 | * @var callback
43 | */
44 | protected $_onWorkerStart = null;
45 |
46 | /**
47 | * Add virtual host.
48 | *
49 | * @param string $domain
50 | * @param string $root_path
51 | * @return void
52 | */
53 | public function addRoot($domain, $root_path)
54 | {
55 | $this->serverRoot[$domain] = $root_path;
56 | }
57 |
58 | /**
59 | * Construct.
60 | *
61 | * @param string $socket_name
62 | * @param array $context_option
63 | */
64 | public function __construct($socket_name, $context_option = array())
65 | {
66 | list(, $address) = explode(':', $socket_name, 2);
67 | parent::__construct('http:' . $address, $context_option);
68 | $this->name = 'WebServer';
69 | }
70 |
71 | /**
72 | * Run webserver instance.
73 | *
74 | * @see Workerman.Worker::run()
75 | */
76 | public function run()
77 | {
78 | $this->_onWorkerStart = $this->onWorkerStart;
79 | $this->onWorkerStart = array($this, 'onWorkerStart');
80 | $this->onMessage = array($this, 'onMessage');
81 | parent::run();
82 | }
83 |
84 | /**
85 | * Emit when process start.
86 | *
87 | * @throws \Exception
88 | */
89 | public function onWorkerStart()
90 | {
91 | if (empty($this->serverRoot)) {
92 | throw new \Exception('server root not set, please use WebServer::addRoot($domain, $root_path) to set server root path');
93 | }
94 | // Init HttpCache.
95 | HttpCache::init();
96 | // Init mimeMap.
97 | $this->initMimeTypeMap();
98 |
99 | // Try to emit onWorkerStart callback.
100 | if ($this->_onWorkerStart) {
101 | try {
102 | call_user_func($this->_onWorkerStart, $this);
103 | } catch (\Exception $e) {
104 | self::log($e);
105 | exit(250);
106 | } catch (\Error $e) {
107 | self::log($e);
108 | exit(250);
109 | }
110 | }
111 | }
112 |
113 | /**
114 | * Init mime map.
115 | *
116 | * @return void
117 | */
118 | public function initMimeTypeMap()
119 | {
120 | $mime_file = Http::getMimeTypesFile();
121 | if (!is_file($mime_file)) {
122 | $this->log("$mime_file mime.type file not fond");
123 | return;
124 | }
125 | $items = file($mime_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
126 | if (!is_array($items)) {
127 | $this->log("get $mime_file mime.type content fail");
128 | return;
129 | }
130 | foreach ($items as $content) {
131 | if (preg_match("/\s*(\S+)\s+(\S.+)/", $content, $match)) {
132 | $mime_type = $match[1];
133 | $workerman_file_extension_var = $match[2];
134 | $workerman_file_extension_array = explode(' ', substr($workerman_file_extension_var, 0, -1));
135 | foreach ($workerman_file_extension_array as $workerman_file_extension) {
136 | self::$mimeTypeMap[$workerman_file_extension] = $mime_type;
137 | }
138 | }
139 | }
140 | }
141 |
142 | /**
143 | * Emit when http message coming.
144 | *
145 | * @param Connection\TcpConnection $connection
146 | * @return void
147 | */
148 | public function onMessage($connection)
149 | {
150 | // REQUEST_URI.
151 | $workerman_url_info = parse_url($_SERVER['REQUEST_URI']);
152 | if (!$workerman_url_info) {
153 | Http::header('HTTP/1.1 400 Bad Request');
154 | $connection->close('400 Bad Request
');
155 | return;
156 | }
157 |
158 | $workerman_path = isset($workerman_url_info['path']) ? $workerman_url_info['path'] : '/';
159 |
160 | $workerman_path_info = pathinfo($workerman_path);
161 | $workerman_file_extension = isset($workerman_path_info['extension']) ? $workerman_path_info['extension'] : '';
162 | if ($workerman_file_extension === '') {
163 | $workerman_path = ($len = strlen($workerman_path)) && $workerman_path[$len - 1] === '/' ? $workerman_path . 'index.php' : $workerman_path . '/index.php';
164 | $workerman_file_extension = 'php';
165 | }
166 |
167 | $workerman_root_dir = isset($this->serverRoot[$_SERVER['SERVER_NAME']]) ? $this->serverRoot[$_SERVER['SERVER_NAME']] : current($this->serverRoot);
168 |
169 | $workerman_file = "$workerman_root_dir/$workerman_path";
170 |
171 | if ($workerman_file_extension === 'php' && !is_file($workerman_file)) {
172 | $workerman_file = "$workerman_root_dir/index.php";
173 | if (!is_file($workerman_file)) {
174 | $workerman_file = "$workerman_root_dir/index.html";
175 | $workerman_file_extension = 'html';
176 | }
177 | }
178 |
179 | // File exsits.
180 | if (is_file($workerman_file)) {
181 | // Security check.
182 | if ((!($workerman_request_realpath = realpath($workerman_file)) || !($workerman_root_dir_realpath = realpath($workerman_root_dir))) || 0 !== strpos($workerman_request_realpath,
183 | $workerman_root_dir_realpath)
184 | ) {
185 | Http::header('HTTP/1.1 400 Bad Request');
186 | $connection->close('400 Bad Request
');
187 | return;
188 | }
189 |
190 | $workerman_file = realpath($workerman_file);
191 |
192 | // Request php file.
193 | if ($workerman_file_extension === 'php') {
194 | $workerman_cwd = getcwd();
195 | chdir($workerman_root_dir);
196 | ini_set('display_errors', 'off');
197 | ob_start();
198 | // Try to include php file.
199 | try {
200 | // $_SERVER.
201 | $_SERVER['REMOTE_ADDR'] = $connection->getRemoteIp();
202 | $_SERVER['REMOTE_PORT'] = $connection->getRemotePort();
203 | include $workerman_file;
204 | } catch (\Exception $e) {
205 | // Jump_exit?
206 | if ($e->getMessage() != 'jump_exit') {
207 | echo $e;
208 | }
209 | }
210 | $content = ob_get_clean();
211 | ini_set('display_errors', 'on');
212 | if (strtolower($_SERVER['HTTP_CONNECTION']) === "keep-alive") {
213 | $connection->send($content);
214 | } else {
215 | $connection->close($content);
216 | }
217 | chdir($workerman_cwd);
218 | return;
219 | }
220 |
221 | // Send file to client.
222 | return self::sendFile($connection, $workerman_file);
223 | } else {
224 | // 404
225 | Http::header("HTTP/1.1 404 Not Found");
226 | $connection->close('404 File not found404 Not Found
');
227 | return;
228 | }
229 | }
230 |
231 | public static function sendFile($connection, $file_path)
232 | {
233 | // Check 304.
234 | $info = stat($file_path);
235 | $modified_time = $info ? date('D, d M Y H:i:s', $info['mtime']) . ' GMT' : '';
236 | if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $info) {
237 | // Http 304.
238 | if ($modified_time === $_SERVER['HTTP_IF_MODIFIED_SINCE']) {
239 | // 304
240 | Http::header('HTTP/1.1 304 Not Modified');
241 | // Send nothing but http headers..
242 | $connection->close('');
243 | return;
244 | }
245 | }
246 |
247 | // Http header.
248 | if ($modified_time) {
249 | $modified_time = "Last-Modified: $modified_time\r\n";
250 | }
251 | $file_size = filesize($file_path);
252 | $file_info = pathinfo($file_path);
253 | $extension = isset($file_info['extension']) ? $file_info['extension'] : '';
254 | $file_name = isset($file_info['filename']) ? $file_info['filename'] : '';
255 | $header = "HTTP/1.1 200 OK\r\n";
256 | if (isset(self::$mimeTypeMap[$extension])) {
257 | $header .= "Content-Type: " . self::$mimeTypeMap[$extension] . "\r\n";
258 | } else {
259 | $header .= "Content-Type: application/octet-stream\r\n";
260 | $header .= "Content-Disposition: attachment; filename=\"$file_name\"\r\n";
261 | }
262 | $header .= "Connection: keep-alive\r\n";
263 | $header .= $modified_time;
264 | $header .= "Content-Length: $file_size\r\n\r\n";
265 | $trunk_limit_size = 1024*1024;
266 | if ($file_size < $trunk_limit_size) {
267 | return $connection->send($header.file_get_contents($file_path), true);
268 | }
269 | $connection->send($header, true);
270 |
271 | // Read file content from disk piece by piece and send to client.
272 | $connection->fileHandler = fopen($file_path, 'r');
273 | $do_write = function()use($connection)
274 | {
275 | // Send buffer not full.
276 | while(empty($connection->bufferFull))
277 | {
278 | // Read from disk.
279 | $buffer = fread($connection->fileHandler, 8192);
280 | // Read eof.
281 | if($buffer === '' || $buffer === false)
282 | {
283 | return;
284 | }
285 | $connection->send($buffer, true);
286 | }
287 | };
288 | // Send buffer full.
289 | $connection->onBufferFull = function($connection)
290 | {
291 | $connection->bufferFull = true;
292 | };
293 | // Send buffer drain.
294 | $connection->onBufferDrain = function($connection)use($do_write)
295 | {
296 | $connection->bufferFull = false;
297 | $do_write();
298 | };
299 | $do_write();
300 | }
301 | }
302 |
--------------------------------------------------------------------------------
/vendor/topthink/think-worker/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------