├── .gitignore ├── src ├── routes │ └── web.php ├── Chat │ ├── lib │ │ ├── start_register.php │ │ ├── start.php │ │ ├── start_businessworker.php │ │ ├── Events.php │ │ └── start_gateway.php │ └── ChatServiceProvider.php ├── migrations │ ├── 2018_05_15_064542_add_uuid_to_users_table.php │ └── 2018_05_15_064600_add_uuid_to_admins_table.php ├── config │ └── chat.php ├── helper │ └── ChatHandleTrait.php ├── Controllers │ └── Chat │ │ └── ChatController.php └── views │ └── chat │ └── chat.blade.php ├── composer.json ├── README.md └── composer.lock /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | .idea/ 3 | -------------------------------------------------------------------------------- /src/routes/web.php: -------------------------------------------------------------------------------- 1 | name('chat-bind'); 5 | 6 | Route::post('/chat/sendmessage', 'Gongjieqi\LaravelChat\Controllers\Chat\ChatController@sendMessage')->name('chat-send'); -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gongjieqi/laravel-chat", 3 | "description": "message server base on workman", 4 | "type": "library", 5 | "authors": [ 6 | { 7 | "name": "Jieqi Gong", 8 | "email": "232183495@qq.com" 9 | } 10 | ], 11 | "require": { 12 | "workerman/gateway-worker": "^3.0", 13 | "illuminate/console": "~5.0", 14 | "illuminate/support": "~5.0", 15 | "illuminate/cache": "~5.0" 16 | }, 17 | "autoload": { 18 | "psr-4": { 19 | "Gongjieqi\\LaravelChat\\": "src/" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # laravel-chat 2 | 这是一个简易版本,结合laravel的用户和workman实现前后台用户聊天的webIM 3 | 4 | 操作步骤: 5 | 1. 在config/app.php 中添加服务提供者: 6 | 7 | Gongjieqi\LaravelChat\Chat\ChatServiceProvider::class, 8 | 9 | 2. artisan vendor:publish 10 | 3. artisan migrate 11 | 4. 配置文件config/chat.php 12 | 参数说明: 13 | 14 | 30行以上的配置,参考workman手册(就是这么懒...) 15 | 16 | 'user' => 'App\User', //前台用户Model 17 | 18 | 'user_table' => 'users', //前台用户表 19 | 20 | 'user_guard' => 'web', //前台用户guard 21 | 22 | 'user_name_filed' => 'name', //前台用户用户名字段 23 | 接下来的就是对应后台用户的响应配置了 24 | 25 | 5. 运行 php app/server/start.php start 26 | 27 | 6. 将chat/chat.blade.php include到对应的模板文件里去 -------------------------------------------------------------------------------- /src/Chat/lib/start_register.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 | use \Workerman\Worker; 15 | use \GatewayWorker\Register; 16 | 17 | // register 服务必须是text协议 18 | $register = new Register($config['registerServer']); 19 | 20 | // 如果不是在根目录启动,则运行runAll方法 21 | if(!defined('GLOBAL_START')) { 22 | Worker::runAll(); 23 | } 24 | 25 | -------------------------------------------------------------------------------- /src/migrations/2018_05_15_064542_add_uuid_to_users_table.php: -------------------------------------------------------------------------------- 1 | string('uuid',100)->nullable(); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | * 25 | * @return void 26 | */ 27 | public function down() 28 | { 29 | Schema::table('users', function (Blueprint $table) { 30 | // 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/migrations/2018_05_15_064600_add_uuid_to_admins_table.php: -------------------------------------------------------------------------------- 1 | string('uuid',100)->nullable(); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | * 25 | * @return void 26 | */ 27 | public function down() 28 | { 29 | Schema::table('admins', function (Blueprint $table) { 30 | // 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Chat/lib/start.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 | use Workerman\Worker; 15 | use Workerman\WebServer; 16 | use GatewayWorker\Gateway; 17 | use GatewayWorker\BusinessWorker; 18 | use Workerman\Autoloader; 19 | 20 | // bussinessWorker 进程 21 | $worker = new BusinessWorker(); 22 | // worker名称 23 | $worker->name = $config['name']; 24 | //'my chat app'; 25 | // bussinessWorker进程数量 26 | $worker->count = $config['work_count']; 27 | //4; 28 | // 服务注册地址 29 | $worker->registerAddress = $config['registerAddress']; 30 | //'127.0.0.1:1238'; 31 | 32 | // 如果不是在根目录启动,则运行runAll方法 33 | if(!defined('GLOBAL_START')) { 34 | Worker::runAll(); 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/config/chat.php: -------------------------------------------------------------------------------- 1 | 'my chat app', 11 | 12 | 13 | 'work_count' => 4, 14 | 15 | 'registerAddress' => '127.0.0.1:1238', 16 | 17 | 'registerServer' => 'text://0.0.0.0:1238', 18 | 19 | 'lanIp' => '127.0.0.1', 20 | 21 | 'gateway_app' => 'my gateway app', 22 | 23 | 'socket_ip' => '0.0.0.0', 24 | 25 | 'socket_from_client_ip' => '192.168.10.10', 26 | 27 | 'start_port' => 4000, 28 | 29 | 'socket_port' => '8282', 30 | /* 31 | |-------------------------------------------------------------------------- 32 | | User Model & Table 33 | |-------------------------------------------------------------------------- 34 | | 35 | */ 36 | 'user' => 'App\User', 37 | 38 | 'user_table' => 'users', 39 | 40 | 'user_guard' => 'web', 41 | 42 | 'user_name_filed' => 'name', 43 | /* 44 | |-------------------------------------------------------------------------- 45 | | Admin Model & Table 46 | |-------------------------------------------------------------------------- 47 | | 48 | */ 49 | 'admin' => 'App\Admin', 50 | 51 | 'admin_table' => 'admins', 52 | 53 | 'admin_guard' => 'admin', 54 | 55 | 'admin_name_filed'=> 'name' 56 | ]; -------------------------------------------------------------------------------- /src/Chat/ChatServiceProvider.php: -------------------------------------------------------------------------------- 1 | publishes([ 19 | __DIR__ . '/../config/chat.php' => config_path('chat.php'), 20 | __DIR__ . '/lib/start_businessworker.php' => app_path('/server/start_businessworker.php'), 21 | __DIR__ . '/lib/start_gateway.php' => app_path('/server/start_gateway.php'), 22 | __DIR__ . '/lib/start_register.php' => app_path('/server/start_register.php'), 23 | __DIR__ . '/lib/Events.php' => app_path('/server/Events.php'), 24 | __DIR__ . '/lib/start.php' => app_path('/server/start.php'), 25 | __DIR__. '/../views/chat/chat.blade.php' => resource_path('views/chat/chat.blade.php'), 26 | //__DIR__. '/../views/chat/user.blade.php' => resource_path('views/chat/user.blade.php') 27 | ]); 28 | 29 | $this->loadMigrationsFrom(__DIR__ . '/../migrations'); 30 | 31 | $this->loadRoutesFrom(__DIR__.'/../routes/web.php'); 32 | // if ($this->app->runningInConsole()) { 33 | // $this->commands([ 34 | // ChatInitCommand::class, 35 | // ]); 36 | // } 37 | } 38 | } -------------------------------------------------------------------------------- /src/helper/ChatHandleTrait.php: -------------------------------------------------------------------------------- 1 | guard($guard)->user()->uuid; 17 | if(empty($uuid)){ 18 | $uuid = Str::random(80); 19 | auth()->guard($guard)->user()->uuid = $uuid; 20 | auth()->guard($guard)->user()->save(); 21 | } 22 | $is_bind = Gateway::getClientIdByUid($uuid); 23 | Gateway::bindUid($client_id,$uuid); 24 | 25 | if($guard == config('chat.user_guard')){ 26 | $name = auth()->guard($guard)->user()->{config('chat.user_name_filed')}; 27 | }else{ 28 | $name = auth()->guard($guard)->user()->{config('chat.admin_name_filed')}; 29 | } 30 | return ['guard'=>$guard,'uuid'=>$uuid,'name'=>$name,'is_bind'=>$is_bind]; 31 | } 32 | 33 | public function getUserListByGroup($group,$online_users) 34 | { 35 | if($group == 'user'){ 36 | $configModel = config('chat.user'); 37 | $name_filed = config('chat.user_name_filed'); 38 | }else{ 39 | $configModel = config('chat.admin'); 40 | $name_filed = config('chat.admin_name_filed'); 41 | } 42 | 43 | $model = new $configModel; 44 | 45 | $users = $model::whereIn('uuid',$online_users)->get([$name_filed.' as name','uuid'])->toArray(); 46 | 47 | foreach ($users as $key=>$user){ 48 | $users[$key]['client_id'] = Gateway::getClientIdByUid($user['uuid']); 49 | } 50 | return $users; 51 | } 52 | } -------------------------------------------------------------------------------- /src/Chat/lib/Events.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 | /** 16 | * 用于检测业务代码死循环或者长时间阻塞等问题 17 | * 如果发现业务卡死,可以将下面declare打开(去掉//注释),并执行php start.php reload 18 | * 然后观察一段时间workerman.log看是否有process_timeout异常 19 | */ 20 | //declare(ticks=1); 21 | 22 | use \GatewayWorker\Lib\Gateway; 23 | 24 | /** 25 | * 主逻辑 26 | * 主要是处理 onConnect onMessage onClose 三个方法 27 | * onConnect 和 onClose 如果不需要可以不用实现并删除 28 | */ 29 | class Events 30 | { 31 | /** 32 | * 当客户端连接时触发 33 | * 如果业务不需此回调可以删除onConnect 34 | * 35 | * @param int $client_id 连接id 36 | */ 37 | public static function onConnect($client_id) { 38 | Gateway::sendToClient($client_id, json_encode(array( 39 | 'type' => 'init', 40 | 'client_id' => $client_id, 41 | 'all_client'=> Gateway::getAllClientSessions(), 42 | ))); 43 | } 44 | 45 | /** 46 | * 当客户端发来消息时触发 47 | * @param int $client_id 连接id 48 | * @param mixed $message 具体消息 49 | */ 50 | public static function onMessage($client_id, $message) { 51 | 52 | } 53 | 54 | /** 55 | * 当用户断开连接时触发 56 | * @param int $client_id 连接id 57 | */ 58 | public static function onClose($client_id) { 59 | Gateway::sendToAll( 60 | json_encode(array( 61 | 'type' => 'offline', 62 | 'uuid'=> Gateway::getUidByClientId($client_id), 63 | 'client_id'=>$client_id, 64 | )) 65 | ); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Chat/lib/start_gateway.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 | use \Workerman\Worker; 15 | use \Workerman\WebServer; 16 | use \GatewayWorker\Gateway; 17 | use \GatewayWorker\BusinessWorker; 18 | use \Workerman\Autoloader; 19 | 20 | // gateway 进程,这里使用Text协议,可以用telnet测试 21 | $gateway = new Gateway('websocket://'.$config['socket_ip'].':'.$config['socket_port']); 22 | // gateway名称,status方便查看 23 | $gateway->name = $config['gateway_app']; 24 | // gateway进程数 25 | $gateway->count = $config['work_count']; 26 | // 本机ip,分布式部署时使用内网ip 27 | $gateway->lanIp = $config['lanIp']; 28 | // 内部通讯起始端口,假如$gateway->count=4,起始端口为4000 29 | // 则一般会使用4000 4001 4002 4003 4个端口作为内部通讯端口 30 | $gateway->startPort = $config['start_port']; 31 | // 服务注册地址 32 | $gateway->registerAddress = $config['registerAddress']; 33 | 34 | // 心跳间隔 35 | //$gateway->pingInterval = 10; 36 | // 心跳数据 37 | //$gateway->pingData = '{"type":"ping"}'; 38 | 39 | /* 40 | // 当客户端连接上来时,设置连接的onWebSocketConnect,即在websocket握手时的回调 41 | $gateway->onConnect = function($connection) 42 | { 43 | $connection->onWebSocketConnect = function($connection , $http_header) 44 | { 45 | // 可以在这里判断连接来源是否合法,不合法就关掉连接 46 | // $_SERVER['HTTP_ORIGIN']标识来自哪个站点的页面发起的websocket链接 47 | if($_SERVER['HTTP_ORIGIN'] != 'http://kedou.workerman.net') 48 | { 49 | $connection->close(); 50 | } 51 | // onWebSocketConnect 里面$_GET $_SERVER是可用的 52 | // var_dump($_GET, $_SERVER); 53 | }; 54 | }; 55 | */ 56 | 57 | // 如果不是在根目录启动,则运行runAll方法 58 | if(!defined('GLOBAL_START')) { 59 | Worker::runAll(); 60 | } 61 | 62 | -------------------------------------------------------------------------------- /src/Controllers/Chat/ChatController.php: -------------------------------------------------------------------------------- 1 | middleware(['web']); 24 | } 25 | 26 | public function bind(Request $request) 27 | { 28 | if(auth(config('chat.user_guard'))->user()){ 29 | $info = $this->bindUser(config('chat.user_guard'),$request->input('client_id')); 30 | 31 | }elseif(auth(config('chat.admin_guard'))->user()){ 32 | $info = $this->bindUser(config('chat.admin_guard'),$request->input('client_id')); 33 | }else{ 34 | $info['guard'] = null; 35 | } 36 | 37 | $group_name = ''; 38 | if ($info['guard'] == config('chat.user_guard')){ 39 | Gateway::joinGroup($request->input('client_id'), 'user'); 40 | $group_name = 'Member'; 41 | }elseif($info['guard'] == config('chat.admin_guard')){ 42 | Gateway::joinGroup($request->input('client_id'), 'admin'); 43 | $group_name = 'Admin'; 44 | }else{ 45 | //Gateway::joinGroup($request->input('client_id'), 'guest'); 46 | } 47 | 48 | 49 | $group = Gateway::getAllGroupIdList(); 50 | foreach ($group as $item){ 51 | $current_group = Gateway::getUidListByGroup($item); 52 | $value = array_values($current_group); 53 | $return[$item] = $this->getUserListByGroup($item,$value); 54 | } 55 | 56 | if(count($info['is_bind']) <= 0){ 57 | //完成绑定,通知所有在线用户 58 | Gateway::sendToUid(array_except(Gateway::getAllUidList(), Gateway::getUidByClientId($request->input('client_id'))),json_encode(array( 59 | 'type' => 'online', 60 | 'uuid'=> Gateway::getUidByClientId($request->input('client_id')), 61 | 'client_id' => $request->input('client_id'), 62 | 'name'=> $info['name'], 63 | 'group'=>$group_name 64 | ))); 65 | } 66 | $return['own']['uuid'] = $info['uuid']; 67 | return $return; 68 | } 69 | 70 | public function sendMessage(Request $request) 71 | { 72 | if($request->input('client_id')){ 73 | Gateway::sendToClient($request->input('client_id'),json_encode(array( 74 | 'type' => 'message', 75 | 'from' => $request->input('from'), 76 | 'message'=> $request->input('message'), 77 | ))); 78 | } 79 | 80 | if($request->input('uuid')){ 81 | Gateway::sendToUid($request->input('uuid'),json_encode(array( 82 | 'type' => 'message', 83 | 'from' => $request->input('from'), 84 | 'message'=> $request->input('message'), 85 | ))); 86 | } 87 | 88 | return ['code'=>200,'message'=>'send message success!']; 89 | } 90 | } -------------------------------------------------------------------------------- /src/views/chat/chat.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 125 | 126 |
127 |
128 | 129 |
130 | 131 |
132 |
133 | 134 |
135 | Chat 136 |
137 |
138 | 139 | 140 |
141 |
142 | 143 |

144 |
145 |
146 |
147 |
148 | 149 | 150 |
151 |
152 | 153 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "fb9535faf59ebba29d6e6a4946db8ef2", 8 | "packages": [ 9 | { 10 | "name": "doctrine/inflector", 11 | "version": "v1.2.0", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/doctrine/inflector.git", 15 | "reference": "e11d84c6e018beedd929cff5220969a3c6d1d462" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://files.phpcomposer.com/files/doctrine/inflector/e11d84c6e018beedd929cff5220969a3c6d1d462.zip", 20 | "reference": "e11d84c6e018beedd929cff5220969a3c6d1d462", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": "^7.0" 25 | }, 26 | "require-dev": { 27 | "phpunit/phpunit": "^6.2" 28 | }, 29 | "type": "library", 30 | "extra": { 31 | "branch-alias": { 32 | "dev-master": "1.2.x-dev" 33 | } 34 | }, 35 | "autoload": { 36 | "psr-4": { 37 | "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector" 38 | } 39 | }, 40 | "notification-url": "https://packagist.org/downloads/", 41 | "license": [ 42 | "MIT" 43 | ], 44 | "authors": [ 45 | { 46 | "name": "Roman Borschel", 47 | "email": "roman@code-factory.org" 48 | }, 49 | { 50 | "name": "Benjamin Eberlei", 51 | "email": "kontakt@beberlei.de" 52 | }, 53 | { 54 | "name": "Guilherme Blanco", 55 | "email": "guilhermeblanco@gmail.com" 56 | }, 57 | { 58 | "name": "Jonathan Wage", 59 | "email": "jonwage@gmail.com" 60 | }, 61 | { 62 | "name": "Johannes Schmitt", 63 | "email": "schmittjoh@gmail.com" 64 | } 65 | ], 66 | "description": "Common String Manipulations with regard to casing and singular/plural rules.", 67 | "homepage": "http://www.doctrine-project.org", 68 | "keywords": [ 69 | "inflection", 70 | "pluralize", 71 | "singularize", 72 | "string" 73 | ], 74 | "time": "2017-07-22T12:18:28+00:00" 75 | }, 76 | { 77 | "name": "illuminate/cache", 78 | "version": "v5.5.40", 79 | "source": { 80 | "type": "git", 81 | "url": "https://github.com/illuminate/cache.git", 82 | "reference": "6fdc951a4a2c9456e1b8fbef68d4d7cde3392e82" 83 | }, 84 | "dist": { 85 | "type": "zip", 86 | "url": "https://files.phpcomposer.com/files/illuminate/cache/6fdc951a4a2c9456e1b8fbef68d4d7cde3392e82.zip", 87 | "reference": "6fdc951a4a2c9456e1b8fbef68d4d7cde3392e82", 88 | "shasum": "" 89 | }, 90 | "require": { 91 | "illuminate/contracts": "5.5.*", 92 | "illuminate/support": "5.5.*", 93 | "php": ">=7.0" 94 | }, 95 | "suggest": { 96 | "illuminate/database": "Required to use the database cache driver (5.5.*).", 97 | "illuminate/filesystem": "Required to use the file cache driver (5.5.*).", 98 | "illuminate/redis": "Required to use the redis cache driver (5.5.*)." 99 | }, 100 | "type": "library", 101 | "extra": { 102 | "branch-alias": { 103 | "dev-master": "5.5-dev" 104 | } 105 | }, 106 | "autoload": { 107 | "psr-4": { 108 | "Illuminate\\Cache\\": "" 109 | } 110 | }, 111 | "notification-url": "https://packagist.org/downloads/", 112 | "license": [ 113 | "MIT" 114 | ], 115 | "authors": [ 116 | { 117 | "name": "Taylor Otwell", 118 | "email": "taylor@laravel.com" 119 | } 120 | ], 121 | "description": "The Illuminate Cache package.", 122 | "homepage": "https://laravel.com", 123 | "time": "2018-01-26T01:40:49+00:00" 124 | }, 125 | { 126 | "name": "illuminate/console", 127 | "version": "v5.5.40", 128 | "source": { 129 | "type": "git", 130 | "url": "https://github.com/illuminate/console.git", 131 | "reference": "e97dc6d355b1d357691c18a54198a45f2cee2084" 132 | }, 133 | "dist": { 134 | "type": "zip", 135 | "url": "https://files.phpcomposer.com/files/illuminate/console/e97dc6d355b1d357691c18a54198a45f2cee2084.zip", 136 | "reference": "e97dc6d355b1d357691c18a54198a45f2cee2084", 137 | "shasum": "" 138 | }, 139 | "require": { 140 | "illuminate/contracts": "5.5.*", 141 | "illuminate/support": "5.5.*", 142 | "php": ">=7.0", 143 | "symfony/console": "~3.3" 144 | }, 145 | "suggest": { 146 | "guzzlehttp/guzzle": "Required to use the ping methods on schedules (~6.0).", 147 | "mtdowling/cron-expression": "Required to use scheduling component (~1.0).", 148 | "symfony/process": "Required to use scheduling component (~3.3)." 149 | }, 150 | "type": "library", 151 | "extra": { 152 | "branch-alias": { 153 | "dev-master": "5.5-dev" 154 | } 155 | }, 156 | "autoload": { 157 | "psr-4": { 158 | "Illuminate\\Console\\": "" 159 | } 160 | }, 161 | "notification-url": "https://packagist.org/downloads/", 162 | "license": [ 163 | "MIT" 164 | ], 165 | "authors": [ 166 | { 167 | "name": "Taylor Otwell", 168 | "email": "taylor@laravel.com" 169 | } 170 | ], 171 | "description": "The Illuminate Console package.", 172 | "homepage": "https://laravel.com", 173 | "time": "2018-03-22T03:22:47+00:00" 174 | }, 175 | { 176 | "name": "illuminate/contracts", 177 | "version": "v5.5.40", 178 | "source": { 179 | "type": "git", 180 | "url": "https://github.com/illuminate/contracts.git", 181 | "reference": "04fbae936ed14e673dddd18a39662f49e7d199f5" 182 | }, 183 | "dist": { 184 | "type": "zip", 185 | "url": "https://files.phpcomposer.com/files/illuminate/contracts/04fbae936ed14e673dddd18a39662f49e7d199f5.zip", 186 | "reference": "04fbae936ed14e673dddd18a39662f49e7d199f5", 187 | "shasum": "" 188 | }, 189 | "require": { 190 | "php": ">=7.0", 191 | "psr/container": "~1.0", 192 | "psr/simple-cache": "~1.0" 193 | }, 194 | "type": "library", 195 | "extra": { 196 | "branch-alias": { 197 | "dev-master": "5.5-dev" 198 | } 199 | }, 200 | "autoload": { 201 | "psr-4": { 202 | "Illuminate\\Contracts\\": "" 203 | } 204 | }, 205 | "notification-url": "https://packagist.org/downloads/", 206 | "license": [ 207 | "MIT" 208 | ], 209 | "authors": [ 210 | { 211 | "name": "Taylor Otwell", 212 | "email": "taylor@laravel.com" 213 | } 214 | ], 215 | "description": "The Illuminate Contracts package.", 216 | "homepage": "https://laravel.com", 217 | "time": "2018-03-20T15:34:35+00:00" 218 | }, 219 | { 220 | "name": "illuminate/support", 221 | "version": "v5.5.40", 222 | "source": { 223 | "type": "git", 224 | "url": "https://github.com/illuminate/support.git", 225 | "reference": "5d2ccb17e526ad537bffc16abc1d516457ae5587" 226 | }, 227 | "dist": { 228 | "type": "zip", 229 | "url": "https://files.phpcomposer.com/files/illuminate/support/5d2ccb17e526ad537bffc16abc1d516457ae5587.zip", 230 | "reference": "5d2ccb17e526ad537bffc16abc1d516457ae5587", 231 | "shasum": "" 232 | }, 233 | "require": { 234 | "doctrine/inflector": "~1.1", 235 | "ext-mbstring": "*", 236 | "illuminate/contracts": "5.5.*", 237 | "nesbot/carbon": "^1.24.1", 238 | "php": ">=7.0" 239 | }, 240 | "replace": { 241 | "tightenco/collect": "<5.5.33" 242 | }, 243 | "suggest": { 244 | "illuminate/filesystem": "Required to use the composer class (5.5.*).", 245 | "symfony/process": "Required to use the composer class (~3.3).", 246 | "symfony/var-dumper": "Required to use the dd function (~3.3)." 247 | }, 248 | "type": "library", 249 | "extra": { 250 | "branch-alias": { 251 | "dev-master": "5.5-dev" 252 | } 253 | }, 254 | "autoload": { 255 | "psr-4": { 256 | "Illuminate\\Support\\": "" 257 | }, 258 | "files": [ 259 | "helpers.php" 260 | ] 261 | }, 262 | "notification-url": "https://packagist.org/downloads/", 263 | "license": [ 264 | "MIT" 265 | ], 266 | "authors": [ 267 | { 268 | "name": "Taylor Otwell", 269 | "email": "taylor@laravel.com" 270 | } 271 | ], 272 | "description": "The Illuminate Support package.", 273 | "homepage": "https://laravel.com", 274 | "time": "2018-03-10T15:44:32+00:00" 275 | }, 276 | { 277 | "name": "nesbot/carbon", 278 | "version": "1.27.0", 279 | "source": { 280 | "type": "git", 281 | "url": "https://github.com/briannesbitt/Carbon.git", 282 | "reference": "ef81c39b67200dcd7401c24363dcac05ac3a4fe9" 283 | }, 284 | "dist": { 285 | "type": "zip", 286 | "url": "https://files.phpcomposer.com/files/briannesbitt/Carbon/ef81c39b67200dcd7401c24363dcac05ac3a4fe9.zip", 287 | "reference": "ef81c39b67200dcd7401c24363dcac05ac3a4fe9", 288 | "shasum": "" 289 | }, 290 | "require": { 291 | "php": ">=5.3.9", 292 | "symfony/translation": "~2.6 || ~3.0 || ~4.0" 293 | }, 294 | "require-dev": { 295 | "friendsofphp/php-cs-fixer": "~2", 296 | "phpunit/phpunit": "^4.8.35 || ^5.7" 297 | }, 298 | "type": "library", 299 | "autoload": { 300 | "psr-4": { 301 | "": "src/" 302 | } 303 | }, 304 | "notification-url": "https://packagist.org/downloads/", 305 | "license": [ 306 | "MIT" 307 | ], 308 | "authors": [ 309 | { 310 | "name": "Brian Nesbitt", 311 | "email": "brian@nesbot.com", 312 | "homepage": "http://nesbot.com" 313 | } 314 | ], 315 | "description": "A simple API extension for DateTime.", 316 | "homepage": "http://carbon.nesbot.com", 317 | "keywords": [ 318 | "date", 319 | "datetime", 320 | "time" 321 | ], 322 | "time": "2018-04-23T09:02:57+00:00" 323 | }, 324 | { 325 | "name": "psr/container", 326 | "version": "1.0.0", 327 | "source": { 328 | "type": "git", 329 | "url": "https://github.com/php-fig/container.git", 330 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" 331 | }, 332 | "dist": { 333 | "type": "zip", 334 | "url": "https://files.phpcomposer.com/files/php-fig/container/b7ce3b176482dbbc1245ebf52b181af44c2cf55f.zip", 335 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", 336 | "shasum": "" 337 | }, 338 | "require": { 339 | "php": ">=5.3.0" 340 | }, 341 | "type": "library", 342 | "extra": { 343 | "branch-alias": { 344 | "dev-master": "1.0.x-dev" 345 | } 346 | }, 347 | "autoload": { 348 | "psr-4": { 349 | "Psr\\Container\\": "src/" 350 | } 351 | }, 352 | "notification-url": "https://packagist.org/downloads/", 353 | "license": [ 354 | "MIT" 355 | ], 356 | "authors": [ 357 | { 358 | "name": "PHP-FIG", 359 | "homepage": "http://www.php-fig.org/" 360 | } 361 | ], 362 | "description": "Common Container Interface (PHP FIG PSR-11)", 363 | "homepage": "https://github.com/php-fig/container", 364 | "keywords": [ 365 | "PSR-11", 366 | "container", 367 | "container-interface", 368 | "container-interop", 369 | "psr" 370 | ], 371 | "time": "2017-02-14T16:28:37+00:00" 372 | }, 373 | { 374 | "name": "psr/log", 375 | "version": "1.0.2", 376 | "source": { 377 | "type": "git", 378 | "url": "https://github.com/php-fig/log.git", 379 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" 380 | }, 381 | "dist": { 382 | "type": "zip", 383 | "url": "https://files.phpcomposer.com/files/php-fig/log/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d.zip", 384 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", 385 | "shasum": "" 386 | }, 387 | "require": { 388 | "php": ">=5.3.0" 389 | }, 390 | "type": "library", 391 | "extra": { 392 | "branch-alias": { 393 | "dev-master": "1.0.x-dev" 394 | } 395 | }, 396 | "autoload": { 397 | "psr-4": { 398 | "Psr\\Log\\": "Psr/Log/" 399 | } 400 | }, 401 | "notification-url": "https://packagist.org/downloads/", 402 | "license": [ 403 | "MIT" 404 | ], 405 | "authors": [ 406 | { 407 | "name": "PHP-FIG", 408 | "homepage": "http://www.php-fig.org/" 409 | } 410 | ], 411 | "description": "Common interface for logging libraries", 412 | "homepage": "https://github.com/php-fig/log", 413 | "keywords": [ 414 | "log", 415 | "psr", 416 | "psr-3" 417 | ], 418 | "time": "2016-10-10T12:19:37+00:00" 419 | }, 420 | { 421 | "name": "psr/simple-cache", 422 | "version": "1.0.1", 423 | "source": { 424 | "type": "git", 425 | "url": "https://github.com/php-fig/simple-cache.git", 426 | "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" 427 | }, 428 | "dist": { 429 | "type": "zip", 430 | "url": "https://files.phpcomposer.com/files/php-fig/simple-cache/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b.zip", 431 | "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", 432 | "shasum": "" 433 | }, 434 | "require": { 435 | "php": ">=5.3.0" 436 | }, 437 | "type": "library", 438 | "extra": { 439 | "branch-alias": { 440 | "dev-master": "1.0.x-dev" 441 | } 442 | }, 443 | "autoload": { 444 | "psr-4": { 445 | "Psr\\SimpleCache\\": "src/" 446 | } 447 | }, 448 | "notification-url": "https://packagist.org/downloads/", 449 | "license": [ 450 | "MIT" 451 | ], 452 | "authors": [ 453 | { 454 | "name": "PHP-FIG", 455 | "homepage": "http://www.php-fig.org/" 456 | } 457 | ], 458 | "description": "Common interfaces for simple caching", 459 | "keywords": [ 460 | "cache", 461 | "caching", 462 | "psr", 463 | "psr-16", 464 | "simple-cache" 465 | ], 466 | "time": "2017-10-23T01:57:42+00:00" 467 | }, 468 | { 469 | "name": "symfony/console", 470 | "version": "v3.4.10", 471 | "source": { 472 | "type": "git", 473 | "url": "https://github.com/symfony/console.git", 474 | "reference": "36f83f642443c46f3cf751d4d2ee5d047d757a27" 475 | }, 476 | "dist": { 477 | "type": "zip", 478 | "url": "https://files.phpcomposer.com/files/symfony/console/36f83f642443c46f3cf751d4d2ee5d047d757a27.zip", 479 | "reference": "36f83f642443c46f3cf751d4d2ee5d047d757a27", 480 | "shasum": "" 481 | }, 482 | "require": { 483 | "php": "^5.5.9|>=7.0.8", 484 | "symfony/debug": "~2.8|~3.0|~4.0", 485 | "symfony/polyfill-mbstring": "~1.0" 486 | }, 487 | "conflict": { 488 | "symfony/dependency-injection": "<3.4", 489 | "symfony/process": "<3.3" 490 | }, 491 | "require-dev": { 492 | "psr/log": "~1.0", 493 | "symfony/config": "~3.3|~4.0", 494 | "symfony/dependency-injection": "~3.4|~4.0", 495 | "symfony/event-dispatcher": "~2.8|~3.0|~4.0", 496 | "symfony/lock": "~3.4|~4.0", 497 | "symfony/process": "~3.3|~4.0" 498 | }, 499 | "suggest": { 500 | "psr/log-implementation": "For using the console logger", 501 | "symfony/event-dispatcher": "", 502 | "symfony/lock": "", 503 | "symfony/process": "" 504 | }, 505 | "type": "library", 506 | "extra": { 507 | "branch-alias": { 508 | "dev-master": "3.4-dev" 509 | } 510 | }, 511 | "autoload": { 512 | "psr-4": { 513 | "Symfony\\Component\\Console\\": "" 514 | }, 515 | "exclude-from-classmap": [ 516 | "/Tests/" 517 | ] 518 | }, 519 | "notification-url": "https://packagist.org/downloads/", 520 | "license": [ 521 | "MIT" 522 | ], 523 | "authors": [ 524 | { 525 | "name": "Fabien Potencier", 526 | "email": "fabien@symfony.com" 527 | }, 528 | { 529 | "name": "Symfony Community", 530 | "homepage": "https://symfony.com/contributors" 531 | } 532 | ], 533 | "description": "Symfony Console Component", 534 | "homepage": "https://symfony.com", 535 | "time": "2018-05-16T08:49:21+00:00" 536 | }, 537 | { 538 | "name": "symfony/debug", 539 | "version": "v3.4.10", 540 | "source": { 541 | "type": "git", 542 | "url": "https://github.com/symfony/debug.git", 543 | "reference": "b28fd73fefbac341f673f5efd707d539d6a19f68" 544 | }, 545 | "dist": { 546 | "type": "zip", 547 | "url": "https://files.phpcomposer.com/files/symfony/debug/b28fd73fefbac341f673f5efd707d539d6a19f68.zip", 548 | "reference": "b28fd73fefbac341f673f5efd707d539d6a19f68", 549 | "shasum": "" 550 | }, 551 | "require": { 552 | "php": "^5.5.9|>=7.0.8", 553 | "psr/log": "~1.0" 554 | }, 555 | "conflict": { 556 | "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" 557 | }, 558 | "require-dev": { 559 | "symfony/http-kernel": "~2.8|~3.0|~4.0" 560 | }, 561 | "type": "library", 562 | "extra": { 563 | "branch-alias": { 564 | "dev-master": "3.4-dev" 565 | } 566 | }, 567 | "autoload": { 568 | "psr-4": { 569 | "Symfony\\Component\\Debug\\": "" 570 | }, 571 | "exclude-from-classmap": [ 572 | "/Tests/" 573 | ] 574 | }, 575 | "notification-url": "https://packagist.org/downloads/", 576 | "license": [ 577 | "MIT" 578 | ], 579 | "authors": [ 580 | { 581 | "name": "Fabien Potencier", 582 | "email": "fabien@symfony.com" 583 | }, 584 | { 585 | "name": "Symfony Community", 586 | "homepage": "https://symfony.com/contributors" 587 | } 588 | ], 589 | "description": "Symfony Debug Component", 590 | "homepage": "https://symfony.com", 591 | "time": "2018-05-16T14:03:39+00:00" 592 | }, 593 | { 594 | "name": "symfony/polyfill-mbstring", 595 | "version": "v1.8.0", 596 | "source": { 597 | "type": "git", 598 | "url": "https://github.com/symfony/polyfill-mbstring.git", 599 | "reference": "3296adf6a6454a050679cde90f95350ad604b171" 600 | }, 601 | "dist": { 602 | "type": "zip", 603 | "url": "https://files.phpcomposer.com/files/symfony/polyfill-mbstring/3296adf6a6454a050679cde90f95350ad604b171.zip", 604 | "reference": "3296adf6a6454a050679cde90f95350ad604b171", 605 | "shasum": "" 606 | }, 607 | "require": { 608 | "php": ">=5.3.3" 609 | }, 610 | "suggest": { 611 | "ext-mbstring": "For best performance" 612 | }, 613 | "type": "library", 614 | "extra": { 615 | "branch-alias": { 616 | "dev-master": "1.8-dev" 617 | } 618 | }, 619 | "autoload": { 620 | "psr-4": { 621 | "Symfony\\Polyfill\\Mbstring\\": "" 622 | }, 623 | "files": [ 624 | "bootstrap.php" 625 | ] 626 | }, 627 | "notification-url": "https://packagist.org/downloads/", 628 | "license": [ 629 | "MIT" 630 | ], 631 | "authors": [ 632 | { 633 | "name": "Nicolas Grekas", 634 | "email": "p@tchwork.com" 635 | }, 636 | { 637 | "name": "Symfony Community", 638 | "homepage": "https://symfony.com/contributors" 639 | } 640 | ], 641 | "description": "Symfony polyfill for the Mbstring extension", 642 | "homepage": "https://symfony.com", 643 | "keywords": [ 644 | "compatibility", 645 | "mbstring", 646 | "polyfill", 647 | "portable", 648 | "shim" 649 | ], 650 | "time": "2018-04-26T10:06:28+00:00" 651 | }, 652 | { 653 | "name": "symfony/translation", 654 | "version": "v3.4.10", 655 | "source": { 656 | "type": "git", 657 | "url": "https://github.com/symfony/translation.git", 658 | "reference": "7047f725e35eab768137c677f8c38e4a2a8e38fb" 659 | }, 660 | "dist": { 661 | "type": "zip", 662 | "url": "https://files.phpcomposer.com/files/symfony/translation/7047f725e35eab768137c677f8c38e4a2a8e38fb.zip", 663 | "reference": "7047f725e35eab768137c677f8c38e4a2a8e38fb", 664 | "shasum": "" 665 | }, 666 | "require": { 667 | "php": "^5.5.9|>=7.0.8", 668 | "symfony/polyfill-mbstring": "~1.0" 669 | }, 670 | "conflict": { 671 | "symfony/config": "<2.8", 672 | "symfony/dependency-injection": "<3.4", 673 | "symfony/yaml": "<3.4" 674 | }, 675 | "require-dev": { 676 | "psr/log": "~1.0", 677 | "symfony/config": "~2.8|~3.0|~4.0", 678 | "symfony/dependency-injection": "~3.4|~4.0", 679 | "symfony/finder": "~2.8|~3.0|~4.0", 680 | "symfony/intl": "^2.8.18|^3.2.5|~4.0", 681 | "symfony/yaml": "~3.4|~4.0" 682 | }, 683 | "suggest": { 684 | "psr/log-implementation": "To use logging capability in translator", 685 | "symfony/config": "", 686 | "symfony/yaml": "" 687 | }, 688 | "type": "library", 689 | "extra": { 690 | "branch-alias": { 691 | "dev-master": "3.4-dev" 692 | } 693 | }, 694 | "autoload": { 695 | "psr-4": { 696 | "Symfony\\Component\\Translation\\": "" 697 | }, 698 | "exclude-from-classmap": [ 699 | "/Tests/" 700 | ] 701 | }, 702 | "notification-url": "https://packagist.org/downloads/", 703 | "license": [ 704 | "MIT" 705 | ], 706 | "authors": [ 707 | { 708 | "name": "Fabien Potencier", 709 | "email": "fabien@symfony.com" 710 | }, 711 | { 712 | "name": "Symfony Community", 713 | "homepage": "https://symfony.com/contributors" 714 | } 715 | ], 716 | "description": "Symfony Translation Component", 717 | "homepage": "https://symfony.com", 718 | "time": "2018-05-21T10:06:52+00:00" 719 | }, 720 | { 721 | "name": "workerman/gateway-worker", 722 | "version": "v3.0.8", 723 | "source": { 724 | "type": "git", 725 | "url": "https://github.com/walkor/GatewayWorker.git", 726 | "reference": "b50f901fb390d790df5bd679942eecdaaf880327" 727 | }, 728 | "dist": { 729 | "type": "zip", 730 | "url": "https://files.phpcomposer.com/files/walkor/GatewayWorker/b50f901fb390d790df5bd679942eecdaaf880327.zip", 731 | "reference": "b50f901fb390d790df5bd679942eecdaaf880327", 732 | "shasum": "" 733 | }, 734 | "require": { 735 | "workerman/workerman": ">=3.1.8" 736 | }, 737 | "type": "library", 738 | "autoload": { 739 | "psr-4": { 740 | "GatewayWorker\\": "./src" 741 | } 742 | }, 743 | "notification-url": "https://packagist.org/downloads/", 744 | "license": [ 745 | "MIT" 746 | ], 747 | "homepage": "http://www.workerman.net", 748 | "keywords": [ 749 | "communication", 750 | "distributed" 751 | ], 752 | "time": "2018-05-08T10:58:29+00:00" 753 | }, 754 | { 755 | "name": "workerman/workerman", 756 | "version": "v3.5.6", 757 | "source": { 758 | "type": "git", 759 | "url": "https://github.com/walkor/Workerman.git", 760 | "reference": "46a77574a5ca39def6dec51ddf350cf50daab309" 761 | }, 762 | "dist": { 763 | "type": "zip", 764 | "url": "https://files.phpcomposer.com/files/walkor/Workerman/46a77574a5ca39def6dec51ddf350cf50daab309.zip", 765 | "reference": "46a77574a5ca39def6dec51ddf350cf50daab309", 766 | "shasum": "" 767 | }, 768 | "require": { 769 | "php": ">=5.3" 770 | }, 771 | "suggest": { 772 | "ext-event": "For better performance. " 773 | }, 774 | "type": "library", 775 | "autoload": { 776 | "psr-4": { 777 | "Workerman\\": "./" 778 | } 779 | }, 780 | "notification-url": "https://packagist.org/downloads/", 781 | "license": [ 782 | "MIT" 783 | ], 784 | "authors": [ 785 | { 786 | "name": "walkor", 787 | "email": "walkor@workerman.net", 788 | "homepage": "http://www.workerman.net", 789 | "role": "Developer" 790 | } 791 | ], 792 | "description": "An asynchronous event driven PHP framework for easily building fast, scalable network applications.", 793 | "homepage": "http://www.workerman.net", 794 | "keywords": [ 795 | "asynchronous", 796 | "event-loop" 797 | ], 798 | "time": "2018-04-11T11:25:52+00:00" 799 | } 800 | ], 801 | "packages-dev": [], 802 | "aliases": [], 803 | "minimum-stability": "stable", 804 | "stability-flags": [], 805 | "prefer-stable": false, 806 | "prefer-lowest": false, 807 | "platform": [], 808 | "platform-dev": [] 809 | } 810 | --------------------------------------------------------------------------------