├── .gitignore ├── .gitmodules ├── CREDITS ├── LICENSE ├── README.md ├── ant-config ├── README.md ├── apps │ ├── ctrl │ │ └── main.php │ ├── dao │ │ └── ConfigList.php │ ├── entity │ │ └── ConfigList.php │ ├── service │ │ ├── ConfigList.php │ │ └── Sync.php │ └── web │ │ └── main.php ├── config │ ├── default │ │ ├── config.php │ │ ├── pdo.php │ │ └── register.php │ ├── public │ │ └── README.md │ └── server │ │ ├── config.php │ │ ├── pdo.php │ │ └── register.php └── webroot │ └── main.php ├── ant-example ├── chat │ ├── apps │ │ ├── ctrl │ │ │ ├── main.php │ │ │ ├── qrcode.php │ │ │ └── ws.php │ │ └── service │ │ │ ├── Demo.php │ │ │ └── WS.php │ ├── config │ │ ├── default │ │ │ ├── config.php │ │ │ └── register.php │ │ ├── socket │ │ │ ├── config.php │ │ │ └── register.php │ │ └── websocket │ │ │ ├── config.php │ │ │ └── register.php │ ├── template │ │ └── default │ │ │ └── qrcode │ │ │ ├── login.php │ │ │ └── wx.php │ └── webroot │ │ └── main.php └── user-center │ ├── apps │ ├── common │ │ └── ERROR.php │ ├── ctrl │ │ ├── login.php │ │ └── main.php │ ├── dao │ │ └── User.php │ ├── entity │ │ └── User.php │ ├── exceptionHandler │ │ └── UserException.php │ └── service │ │ ├── Demo.php │ │ └── User.php │ ├── config │ ├── default │ │ ├── config.php │ │ └── register.php │ ├── public │ │ └── pdo.php │ └── socket │ │ ├── config.php │ │ └── register.php │ └── webroot │ └── main.php ├── ant-ext └── MessagePacker.cpp ├── ant-lib ├── common │ ├── Consts.php │ ├── ERROR.php │ ├── LoadClass.php │ ├── Log.php │ ├── Utils.php │ └── VaildInput.php ├── config │ └── README.md ├── ctrl │ ├── Base.php │ ├── RestBase.php │ └── antConfigAgent.php ├── dao │ ├── Auto.php │ └── Base.php ├── entity │ └── Base.php ├── exceptionHandler │ ├── BaseException.php │ ├── ConfigException.php │ ├── DaoException.php │ ├── InputVaildException.php │ ├── PackerException.php │ ├── ParamException.php │ ├── SchedulerException.php │ └── SoaException.php ├── service │ ├── AntConfigAgent.php │ └── Base.php └── socket │ ├── Handler │ ├── Proxy.php │ └── Soa.php │ ├── Http.php │ ├── Tcp.php │ ├── Udp.php │ └── WebSocket.php ├── ant-manager └── README.md ├── ant-monitor ├── README.md ├── apps │ └── ctrl │ │ └── dot.php ├── config │ ├── default │ │ ├── config.php │ │ └── register.php │ └── public │ │ └── README └── webroot │ └── main.php ├── ant-proxy ├── README.md ├── apps │ └── ctrl │ │ └── main.php ├── config │ └── mysql │ │ ├── config.php │ │ ├── pdo.php │ │ └── register.php └── webroot │ └── main.php ├── ant-register ├── README.md ├── apps │ ├── common │ │ ├── ERROR.php │ │ └── Timer.php │ ├── ctrl │ │ └── main.php │ ├── dao │ │ ├── ServiceList.php │ │ └── Subscriber.php │ ├── entity │ │ ├── ServiceList.php │ │ └── Subscriber.php │ ├── exceptionHandler │ │ └── RegisterException.php │ └── service │ │ ├── ServiceList.php │ │ └── Subscriber.php ├── config │ ├── public │ │ └── README │ └── register │ │ ├── config.php │ │ ├── pdo.php │ │ └── register.php ├── sql │ └── register_center.sql └── webroot │ └── main.php ├── ant-rpc ├── README.md ├── packer │ ├── Adapter │ │ └── Ant.php │ ├── Factory.php │ ├── IPacker.php │ └── Result.php ├── scheduler │ ├── Adapter │ │ └── Vote.php │ ├── Factory.php │ ├── ISelector.php │ └── Scheduler.php └── sdk │ ├── ConfigClient.php │ ├── HttpClient.php │ ├── LoadService.php │ ├── MonitorClient.php │ ├── TcpClient.php │ ├── UdpClient.php │ └── antClient.go └── example └── demo.php /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | *.log 3 | ant-lib/config/*.php 4 | public/*.php 5 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "zphp"] 2 | path = zphp 3 | url = https://github.com/shenzhe/zphp.git 4 | -------------------------------------------------------------------------------- /CREDITS: -------------------------------------------------------------------------------- 1 | shenzhe(shenzhe163@gmail.com) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright Tianfeng.Han [mikan.tenny@gmail.com] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ant 2 | 3 | 由来 4 | === 5 | 6 | 蚂蚁个体虽小,但有良好的服务分工和治理,使得整个蚂蚁世界井然有序 7 | 8 | 目标 9 | === 10 | 服务化目前是各大公司的趋势,但php世界很明显缺少一个比较好的服务化治理框架, Ant致力于提供一个纯php的分布式服务化框架,提供高性能、透明的服务化治理解决方案 11 | 12 | 模块 13 | === 14 | 15 | | 模块 | 作用 | 一期目标 | 进展 | 16 | | ------------- |:-------------:|:-------------:|:-------------:| 17 | | ant-register | 统一注册中心|基于mysql实现, 实现服务注册/发现/故障摘除等基础功能| done| 18 | | ant-monitor | 统一监控中心 |实现调用方的性能监控(包含网络时间)
服务提供方的性能监控(不包含网络时间)|done| 19 | | ant-lib | 公用库 |提供一些公用包
如: exception, 一些base类, socket handler|done| 20 | | ant-rpc | 统一rpc协议模块 |只支持 自定义包头+包体的协议,包头,包体都是json串
实现全局的RequestId
服务的基础调度
tcp/http sdk支持|done| 21 | | ant-config | 统一配置模块 |按服务名粒度,支持配置更新、下发、热加载,|doing (80%)| 22 | |ant-example| 示例服务模块 | 两个示例模块,跑通整个流程,实现相互的调用|done| 23 | 24 | 依赖 25 | === 26 | zphp 27 | 28 | swoole 29 | 30 | 运行 31 | == 32 | coming soon 33 | -------------------------------------------------------------------------------- /ant-config/README.md: -------------------------------------------------------------------------------- 1 | config分为二大模块 2 | 3 | server 4 | ====== 5 | config 服务端 6 | config mis 7 | 8 | agent 9 | ===== 10 | config agent -------------------------------------------------------------------------------- /ant-config/apps/ctrl/main.php: -------------------------------------------------------------------------------- 1 | getString('key'); 23 | $serviceName = $this->getString('serviceName'); 24 | /** 25 | * @var $service \service\ConfigList 26 | */ 27 | $service = LoadClass::getService('ConfigList'); 28 | $record = $service->fetchOne([ 29 | 'serviceName=' => "'{$serviceName}'", 30 | 'item=' => "'{$key}'" 31 | ]); 32 | return $this->getView([ 33 | 'record' => $record 34 | ]); 35 | } 36 | 37 | /** 38 | * @return array 39 | * @desc 获取某服务所有的配置 40 | */ 41 | public function all() 42 | { 43 | $serviceName = $this->getString('serviceName'); 44 | return $this->getView([ 45 | 'list' => LoadClass::getService('ConfigList')->fetchAll([ 46 | 'serviceName=' => "'{$serviceName}'" 47 | ]) 48 | ]); 49 | } 50 | } -------------------------------------------------------------------------------- /ant-config/apps/dao/ConfigList.php: -------------------------------------------------------------------------------- 1 | add([ 20 | 'serviceName' => $serviceName, 21 | 'item' => $item, 22 | 'value' => $value, 23 | ]); 24 | if ($id) { 25 | LoadClass::getService('Sync')->syncId($id); 26 | } 27 | return $id; 28 | } 29 | 30 | public function update($id, $item, $value) 31 | { 32 | $ret = LoadClass::getDao('ConfigList')->update([ 33 | 'item' => $item, 34 | 'value' => $value 35 | ], ['id=' => $id]); 36 | if ($ret) { 37 | LoadClass::getService('Sync')->syncId($id); 38 | } 39 | return $ret; 40 | } 41 | 42 | public function remove($id) 43 | { 44 | $record = LoadClass::getDao('ConfigList')->fetchById($id); 45 | if ($record) { 46 | $ret = LoadClass::getDao('ConfigList')->remove([ 47 | 'id=' => $id 48 | ]); 49 | if ($ret) { 50 | LoadClass::getService('Sync')->removeKey($record->serviceName, $record->item); 51 | } 52 | } 53 | } 54 | 55 | public function removeService($serviceName) 56 | { 57 | $ret = LoadClass::getDao('ConfigList')->remove([ 58 | 'serviceName=' => "'{$serviceName}'" 59 | ]); 60 | if ($ret) { 61 | LoadClass::getService('Sync')->removeAll($serviceName); 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /ant-config/apps/service/Sync.php: -------------------------------------------------------------------------------- 1 | syncToClient($serviceName, 'syncAll'); 26 | } 27 | 28 | /** 29 | * @param $serviceName 30 | * @param $id 31 | * @desc 配置变更同步到所有的服务器 32 | */ 33 | public function syncId($serviceName, $id) 34 | { 35 | $record = LoadClass::getService('ConfigList')->fetchById($id); 36 | if (empty($record)) { 37 | return; 38 | } 39 | 40 | return $this->syncToClient($serviceName, 'sync', $record); 41 | } 42 | 43 | /** 44 | * @param $serviceName 45 | * @desc 删除所有的配置 46 | */ 47 | public function removeAll($serviceName) 48 | { 49 | return $this->syncToClient($serviceName, 'removeAll'); 50 | } 51 | 52 | /** 53 | * @param $serviceName 54 | * @param $key 55 | * @desc 删除某个配置 56 | */ 57 | public function removeKey($serviceName, $key) 58 | { 59 | $this->syncToClient($serviceName, 'remove', $key); 60 | } 61 | 62 | /** 63 | * @param $serviceName 64 | * @param $method 65 | * @param $record 66 | * @desc 配置同步到所有的client 67 | */ 68 | private function syncToClient($serviceName, $method, $record) 69 | { 70 | $soaConfig = ZConfig::get('soa'); 71 | if (empty($soaConfig)) { 72 | return; 73 | } 74 | $rpcClient = new TcpClient($soaConfig['ip'], $soaConfig['port'], $soaConfig['timeOut']); 75 | $data = $rpcClient->setApi('main')->call('getList', [ 76 | 'serviceName' => $serviceName, 77 | ]); 78 | if(!$data) { 79 | return; 80 | } 81 | $data = $data->getData(); 82 | if (!empty($data['serviceList'])) { 83 | $serverList = $data['serviceList']; 84 | foreach ($serverList as $sub) { 85 | if ($sub['serverType'] == Swoole::TYPE_TCP) { 86 | $service = new TcpClient($sub['ip'], $sub['port']); 87 | } elseif ($sub['serverType'] == Swoole::TYPE_UDP) { 88 | $service = new UdpClient($sub['ip'], $sub['port']); 89 | } else { 90 | continue; 91 | } 92 | $service->setApi('antConfigAgent')->call($method, [ 93 | 'key'=>$record 94 | ]); 95 | } 96 | } 97 | return; 98 | } 99 | } -------------------------------------------------------------------------------- /ant-config/apps/web/main.php: -------------------------------------------------------------------------------- 1 | getString('key'); 23 | $serviceName = $this->getString('serviceName'); 24 | $value = $this->getString('value'); 25 | /** 26 | * @var $service \service\ConfigList 27 | */ 28 | $service = LoadClass::getService('ConfigList'); 29 | $id = $service->add($serviceName, $key, $value); 30 | return $this->getView([ 31 | 'id' => $id 32 | ]); 33 | } 34 | 35 | /** 36 | * @return array 37 | * @desc 更新key 38 | */ 39 | public function update() 40 | { 41 | $id = $this->getInteger('id'); 42 | $key = $this->getString('key'); 43 | $value = $this->getString('value'); 44 | /** 45 | * @var $service \service\ConfigList 46 | */ 47 | $service = LoadClass::getService('ConfigList'); 48 | $ret = $service->update($id, $key, $value); 49 | return $this->getView([ 50 | 'ret' => $ret 51 | ]); 52 | } 53 | 54 | /** 55 | * @return array 56 | * @desc 获取某服务所有的配置 57 | */ 58 | public function all() 59 | { 60 | $serviceName = $this->getString('serviceName'); 61 | return $this->getView([ 62 | 'list' => LoadClass::getService('ConfigList')->fetchAll([ 63 | 'serviceName=' => "'{$serviceName}'" 64 | ]) 65 | ]); 66 | } 67 | 68 | 69 | } -------------------------------------------------------------------------------- /ant-config/config/default/config.php: -------------------------------------------------------------------------------- 1 | 'Cli', 9 | 'project_name' => 'ant-config-center-admin', 10 | 'ctrl_path' => 'web', 11 | 'project' => [ 12 | 'debug_mode' => 0, //打开调试模式 13 | ], 14 | 'lib_path' => array( 15 | 'ant-lib' => ZPHP::getRootPath() . DS . '..' . DS . 'ant-lib', 16 | 'ant-rpc' => ZPHP::getRootPath() . DS . '..' . DS . 'ant-rpc', 17 | ), 18 | ); -------------------------------------------------------------------------------- /ant-config/config/default/pdo.php: -------------------------------------------------------------------------------- 1 | array( 4 | 'common' => array( 5 | 'dsn' => 'mysql:host=127.0.0.1;port=3306', //dsn地址 6 | 'name' => 'common', //自定义名称 7 | 'user' => 'root', // db用户名 8 | 'pass' => '123456', //db密码 9 | 'dbname' => 'config_center', //db默认数据库 10 | 'charset' => 'UTF8', //db默认编码 11 | 'pconnect' => false, //是否开启持久连接,swoole模式必需关闭 12 | 'ping' => 1, //是否开始ping检测 13 | 'pingtime' => 7200, //ping检测时间 14 | ), 15 | ), 16 | ]; -------------------------------------------------------------------------------- /ant-config/config/default/register.php: -------------------------------------------------------------------------------- 1 | array( 10 | 'ip' => '10.94.107.22', 11 | 'port' => 9949 12 | ), 13 | ); -------------------------------------------------------------------------------- /ant-config/config/public/README.md: -------------------------------------------------------------------------------- 1 | 公用配置 -------------------------------------------------------------------------------- /ant-config/config/server/config.php: -------------------------------------------------------------------------------- 1 | 'Ant', 9 | 'project_name' => 'ant-config-center', 10 | 'project' => [ 11 | 'debug_mode' => 0, //打开调试模式 12 | ], 13 | 'socket' => array( 14 | 'host' => '0.0.0.0', //socket 监听ip 15 | 'port' => 8500, //socket 监听端口 16 | 'server_type' => Swoole::TYPE_TCP, //socket 业务模型 tcp/udp/http/websocket 17 | 'daemonize' => 1, //是否开启守护进程 18 | 'work_mode' => 3, //工作模式:1:单进程单线程 2:多线程 3: 多进程 19 | 'worker_num' => 32, //工作进程数 20 | 'task_worker_num' => 32, //工作进程数 21 | 'max_request' => 0, //单个进程最大处理请求数 22 | 'addlisten' => array( //开启udp监听 23 | 'ip' => '0.0.0.0', 24 | 'port' => 8501 25 | ), 26 | ), 27 | ); 28 | -------------------------------------------------------------------------------- /ant-config/config/server/pdo.php: -------------------------------------------------------------------------------- 1 | array( 4 | 'common' => array( 5 | 'dsn' => 'mysql:host=127.0.0.1;port=3306', //dsn地址 6 | 'name' => 'common', //自定义名称 7 | 'user' => 'root', // db用户名 8 | 'pass' => '123456', //db密码 9 | 'dbname' => 'config_center', //db默认数据库 10 | 'charset' => 'UTF8', //db默认编码 11 | 'pconnect' => false, //是否开启持久连接,swoole模式必需关闭 12 | 'ping' => 1, //是否开始ping检测 13 | 'pingtime' => 7200, //ping检测时间 14 | ), 15 | ), 16 | ]; -------------------------------------------------------------------------------- /ant-config/config/server/register.php: -------------------------------------------------------------------------------- 1 | array( 10 | 'ip' => '10.94.107.22', 11 | 'port' => 9949 12 | ), 13 | ); -------------------------------------------------------------------------------- /ant-config/webroot/main.php: -------------------------------------------------------------------------------- 1 | getView([ 12 | 'name'=>'demo' 13 | ]); 14 | } 15 | 16 | public function test() 17 | { 18 | $method = $this->getString('method', 'main'); 19 | return $this->getView(LoadClass::getService('Demo')->demo($method)); 20 | } 21 | } -------------------------------------------------------------------------------- /ant-example/chat/apps/ctrl/qrcode.php: -------------------------------------------------------------------------------- 1 | getView([ 21 | 'code' => uniqid('qrcode_'), 22 | 'ws_url' => 'ws://' . Utils::getLocalIp() . ':' . ZConfig::getField('socket', 'port') . '/', 23 | ]); 24 | } 25 | 26 | public function wx() 27 | { 28 | Request::setViewMode('Php'); 29 | return $this->getView([ 30 | 'code' => $this->getString('code'), 31 | ]); 32 | } 33 | 34 | public function check() 35 | { 36 | $code = $this->getString('code'); 37 | $name = $this->getString('name'); 38 | $password = $this->getString('password'); 39 | 40 | $service = LoadService::getService('user-center'); 41 | $result = $service->setApi('login')->call('check', [ 42 | 'name' => $name, 43 | 'password' => $password 44 | ]); 45 | $body = $result->getBody(); 46 | $ret = $this->getView([ 47 | 'name' => $body['data']['userInfo']['name'] 48 | ]); 49 | 50 | $fd = ZCache::getInstance('Task')->get($code); 51 | Log::info([$code, $fd], 'task_cache'); 52 | if ($fd) { 53 | $socket = Request::getSocket(); 54 | $socket->push($fd, Response::getContent($ret)); 55 | } 56 | return $ret; 57 | } 58 | 59 | public function all() 60 | { 61 | return $this->getView([ 62 | 'cache' => ZCache::getInstance('Task')->all() 63 | ]); 64 | } 65 | 66 | 67 | public function show() 68 | { 69 | $id = $this->getInteger('id'); 70 | $service = LoadService::getService('user-center'); 71 | $result = $service->setApi('main')->call('show', [ 72 | 'id' => $id, 73 | ]); 74 | $body = $result->getBody(); 75 | 76 | return $this->getView([ 77 | 'userInfo' => $body['data']['userInfo'] 78 | ]); 79 | } 80 | } -------------------------------------------------------------------------------- /ant-example/chat/apps/ctrl/ws.php: -------------------------------------------------------------------------------- 1 | getString('code'); 15 | $fd = $this->getInteger('_fd'); 16 | LoadClass::getService('WS')->open($code, $fd); 17 | Log::info([$code, $fd], 'task_cache'); 18 | } 19 | 20 | public function close() 21 | { 22 | $fd = $this->getInteger('_fd'); 23 | LoadClass::getService('WS')->close($fd); 24 | } 25 | } -------------------------------------------------------------------------------- /ant-example/chat/apps/service/Demo.php: -------------------------------------------------------------------------------- 1 | call($method, $params); 21 | //也可以这么执行 22 | //$result = $service->{$method}($params); 23 | //ex:$result = $service->main($params); 24 | //获取结果 25 | $body = $result->getBody(); 26 | return $body['data']; 27 | } 28 | 29 | /** 30 | * @desc 并行调用示例, 31 | */ 32 | public function multi() 33 | { 34 | 35 | $senders = []; 36 | 37 | //执行api1远程调用,返回一个唯一的请求Id 38 | $service2 = LoadService::getService('user-center'); 39 | $requestId = $service2->multiCall('api1'); 40 | $senders[$requestId] = null; 41 | 42 | $service3 = LoadService::getService('api-demo3'); 43 | $requestId = $service3->multiCall('api1'); 44 | $senders[$requestId] = null; 45 | 46 | $service4 = LoadService::getService('api-demo4'); 47 | $requestId = $service4->multiCall('api1'); 48 | $senders[$requestId] = null; 49 | 50 | //获取执行结果 51 | $results = $service4->multiReceive(); 52 | $results += $senders; 53 | return $results; 54 | } 55 | } -------------------------------------------------------------------------------- /ant-example/chat/apps/service/WS.php: -------------------------------------------------------------------------------- 1 | set($code, $fd, 0); 20 | $cache->set($fd, $code, 0); 21 | return true; 22 | } 23 | 24 | public function close($fd) 25 | { 26 | $cache = ZCache::getInstance('Task'); 27 | $code = $cache->get($fd); 28 | $cache->delete($fd); 29 | $cache->delete($code); 30 | } 31 | } -------------------------------------------------------------------------------- /ant-example/chat/config/default/config.php: -------------------------------------------------------------------------------- 1 | (PHP_SAPI === 'cli') ? 'Cli' : 'Http', 7 | 'app_path' => 'apps', 8 | 'ctrl_path' => 'ctrl', 9 | 'lib_path' => array( 10 | 'ant-lib' => ZPHP::getRootPath() . DS . '..' . DS . '..' . DS . 'ant-lib', 11 | 'ant-rpc' => ZPHP::getRootPath() . DS . '..' . DS . '..' . DS . 'ant-rpc', 12 | ), 13 | 'loadend_hook' => function () { 14 | Config::mergePath(dirname(__DIR__) . DS . 'public'); 15 | }, 16 | 'project' => [ 17 | 'default_ctrl_name' => 'main', //默认入口控制器 18 | 'debug_mode' => 0, //打开调试模式 19 | 'protocol' => 'Ant', 20 | 'view_mode' => 'Ant', 21 | 'exception_handler' => 'exceptionHandler\BaseException::exceptionHandler', 22 | 'fatal_handler' => 'exceptionHandler\BaseException::fatalHandler', 23 | 'error_handler' => 'exceptionHandler\BaseException::errorHandler', 24 | ], 25 | ); 26 | -------------------------------------------------------------------------------- /ant-example/chat/config/default/register.php: -------------------------------------------------------------------------------- 1 | array( 5 | 'ip' => '10.94.107.22', 6 | 'port' => 9949, 7 | 'timeOut' => 5000 8 | ), 9 | ); -------------------------------------------------------------------------------- /ant-example/chat/config/socket/config.php: -------------------------------------------------------------------------------- 1 | 'Ant', 7 | 'project_name' => 'api-demo', 8 | 'project' => [ 9 | 'debug_mode' => 0, //打开调试模式 10 | ], 11 | 'lib_path' => [ 12 | 'ant-lib' => ZPHP::getRootPath() . DS . '..' . DS . '..' . DS . 'ant-lib', 13 | 'ant-rpc' => ZPHP::getRootPath() . DS . '..' . DS . '..' . DS . 'ant-rpc', 14 | ], 15 | 'socket' => array( 16 | 'host' => '0.0.0.0', //socket 监听ip 17 | 'port' => 7101, //socket 监听端口 18 | 'server_type' => Swoole::TYPE_TCP, //socket 业务模型 tcp/udp/http/websocket 19 | 'daemonize' => 0, //是否开启守护进程 20 | 'work_mode' => 3, //工作模式:1:单进程单线程 2:多线程 3: 多进程 21 | 'worker_num' => 32, //工作进程数 22 | 'task_worker_num' => 32, //工作进程数 23 | 'max_request' => 0, //单个进程最大处理请求数 24 | 'addlisten' => array( //开启udp监听 25 | 'ip' => '0.0.0.0', 26 | 'port' => 7111 27 | ), 28 | ), 29 | ); 30 | -------------------------------------------------------------------------------- /ant-example/chat/config/socket/register.php: -------------------------------------------------------------------------------- 1 | array( 4 | 'ip' => '10.94.107.22', //注册服务器ip 5 | 'port' => 9949, //注册服务器port 6 | ), 7 | ); -------------------------------------------------------------------------------- /ant-example/chat/config/websocket/config.php: -------------------------------------------------------------------------------- 1 | 'Ant', 7 | 'project_name' => 'chat-ws', 8 | 'project' => [ 9 | 'debug_mode' => 0, //打开调试模式 10 | 'app_host' => '' 11 | ], 12 | 'lib_path' => [ 13 | 'ant-lib' => ZPHP::getRootPath() . DS . '..' . DS . '..' . DS . 'ant-lib', 14 | 'ant-rpc' => ZPHP::getRootPath() . DS . '..' . DS . '..' . DS . 'ant-rpc', 15 | ], 16 | 'socket' => array( 17 | 'host' => '0.0.0.0', //socket 监听ip 18 | 'port' => 7105, //socket 监听端口 19 | 'server_type' => Swoole::TYPE_WEBSOCKET, //socket 业务模型 tcp/udp/http/websocket 20 | 'daemonize' => 1, //是否开启守护进程 21 | 'work_mode' => 3, //工作模式:1:单进程单线程 2:多线程 3: 多进程 22 | 'worker_num' => 32, //工作进程数 23 | 'task_worker_num' => 32, //工作进程数 24 | 'max_request' => 0, //单个进程最大处理请求数 25 | 'addlisten' => array( //开启udp监听 26 | 'ip' => '0.0.0.0', 27 | 'port' => 7115 28 | ), 29 | 'on_open_callback' => ['ws', 'open'], 30 | 'on_close_callback' => ['ws', 'close'], 31 | ), 32 | ); 33 | -------------------------------------------------------------------------------- /ant-example/chat/config/websocket/register.php: -------------------------------------------------------------------------------- 1 | array( 4 | 'ip' => '10.94.107.22', //注册服务器ip 5 | 'port' => 9949, //注册服务器port 6 | ), 7 | ); -------------------------------------------------------------------------------- /ant-example/chat/template/default/qrcode/login.php: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 扫码登录 10 | 11 | 12 |

未登录

13 |

14 | 15 |

16 | 43 | 44 | -------------------------------------------------------------------------------- /ant-example/chat/template/default/qrcode/wx.php: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 扫码登录 11 | 12 | 13 |
14 |

15 |

16 |

17 | 18 | 19 |

20 |
21 | 22 | -------------------------------------------------------------------------------- /ant-example/chat/webroot/main.php: -------------------------------------------------------------------------------- 1 | getString('name'); 15 | $password = $this->getString('password'); 16 | 17 | return $this->getView([ 18 | 'userInfo' => LoadClass::getService('User')->check($name, $password) 19 | ]); 20 | } 21 | 22 | public function register() 23 | { 24 | $name = $this->getString('name'); 25 | $password = $this->getString('password'); 26 | return $this->getView([ 27 | 'userInfo' => LoadClass::getService('User')->register($name, $password) 28 | ]); 29 | } 30 | } -------------------------------------------------------------------------------- /ant-example/user-center/apps/ctrl/main.php: -------------------------------------------------------------------------------- 1 | getView([ 15 | 'config' => ConfigClient::get('test'), 16 | 'name' => 'demo2', 17 | ]); 18 | } 19 | 20 | public function test() 21 | { 22 | $method = $this->getString('method', 'main'); 23 | return $this->getView(LoadClass::getService('Demo')->demo($method)); 24 | } 25 | 26 | public function show() 27 | { 28 | $id = $this->getInteger('id'); 29 | return $this->getView([ 30 | 'userInfo' => LoadClass::getService('User')->show($id), 31 | ] 32 | ); 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /ant-example/user-center/apps/dao/User.php: -------------------------------------------------------------------------------- 1 | $this->id, 26 | 'name' => $this->name, 27 | 'avatar' => $this->avatar, 28 | ]; 29 | } 30 | } -------------------------------------------------------------------------------- /ant-example/user-center/apps/exceptionHandler/UserException.php: -------------------------------------------------------------------------------- 1 | call($method); 19 | $body = $result->getBody(); 20 | return $body['data']; 21 | } 22 | } -------------------------------------------------------------------------------- /ant-example/user-center/apps/service/User.php: -------------------------------------------------------------------------------- 1 | fetchOne([ 22 | 'name=' => "'{$name}'", 23 | 'password=' => "'{$password}'", 24 | ]); 25 | 26 | if (empty($userInfo)) { 27 | throw new UserException("user empty", ERROR::USER_EMPTY); 28 | } 29 | return $userInfo; 30 | } 31 | 32 | public function register($name, $password) 33 | { 34 | $dao = LoadClass::getDao('User'); 35 | $userInfo = $dao->fetchOne([ 36 | 'name=' => "'{$name}'" 37 | ]); 38 | if (!empty($userInfo)) { 39 | throw new UserException("user exists", ERROR::USER_EXISTS); 40 | } 41 | 42 | $userInfo = new \entity\User(); 43 | $userInfo->name = $name; 44 | $userInfo->password = $password; 45 | $id = $dao->add($userInfo); 46 | if (!$id) { 47 | throw new UserException("user register error", ERROR::USER_REGISTER_ERROR); 48 | } 49 | $userInfo->id = $id; 50 | return $userInfo; 51 | 52 | } 53 | 54 | public function show($id) 55 | { 56 | $dao = LoadClass::getDao('User'); 57 | $userInfo = $dao->fetchById($id); 58 | if (empty($userInfo)) { 59 | throw new UserException('user empty', ERROR::USER_NO_EXISTS); 60 | } 61 | return $userInfo->getInfo(); 62 | } 63 | } -------------------------------------------------------------------------------- /ant-example/user-center/config/default/config.php: -------------------------------------------------------------------------------- 1 | (PHP_SAPI === 'cli') ? 'Cli' : 'Http', 8 | 'app_path' => 'apps', 9 | 'ctrl_path' => 'ctrl', 10 | 'lib_path' => array( 11 | 'ant-lib' => ZPHP::getRootPath() . DS . '..' . DS . '..' . DS . 'ant-lib', 12 | 'ant-rpc' => ZPHP::getRootPath() . DS . '..' . DS . '..' . DS . 'ant-rpc', 13 | ), 14 | 'loadend_hook' => function () { 15 | Config::mergePath(dirname(__DIR__) . DS . 'public'); 16 | }, 17 | 'project' => [ 18 | 'default_ctrl_name' => 'main', //默认入口控制器 19 | 'debug_mode' => 0, //打开调试模式 20 | 'protocol' => 'Ant', 21 | 'view_mode' => 'Ant', 22 | 'exception_handler' => 'exceptionHandler\BaseException::exceptionHandler', 23 | 'fatal_handler' => 'exceptionHandler\BaseException::fatalHandler', 24 | 'error_handler' => 'exceptionHandler\BaseException::errorHandler', 25 | ], 26 | ); 27 | -------------------------------------------------------------------------------- /ant-example/user-center/config/default/register.php: -------------------------------------------------------------------------------- 1 | array( 11 | 'ip' => '10.94.107.22', 12 | 'port' => 9949, 13 | 'timeOut' => 5000 14 | ), 15 | ); -------------------------------------------------------------------------------- /ant-example/user-center/config/public/pdo.php: -------------------------------------------------------------------------------- 1 | array( 4 | 'common' => array( 5 | 'dsn' => 'mysql:host=127.0.0.1;port=3306', //dsn地址 6 | 'name' => 'common', //自定义名称 7 | 'user' => 'root', // db用户名 8 | 'pass' => '123456', //db密码 9 | 'dbname' => 'user_center', //db默认数据库 10 | 'charset' => 'UTF8', //db默认编码 11 | 'pconnect' => false, //是否开启持久连接,swoole模式必需关闭 12 | 'ping' => 1, //是否开始ping检测 13 | 'pingtime' => 7200, //ping检测时间 14 | ), 15 | ), 16 | ]; -------------------------------------------------------------------------------- /ant-example/user-center/config/socket/config.php: -------------------------------------------------------------------------------- 1 | 'Ant', 7 | 'project_name' => 'user-center', //服务名称 8 | 'project' => [ 9 | 'debug_mode' => 0, //是否打开调试模式 10 | ], 11 | 'lib_path' => [ 12 | 'ant-lib' => ZPHP::getRootPath() . DS . '..' . DS . '..' . DS . 'ant-lib', 13 | 'ant-rpc' => ZPHP::getRootPath() . DS . '..' . DS . '..' . DS . 'ant-rpc', 14 | ], 15 | 'socket' => array( 16 | 'host' => '0.0.0.0', //socket 监听ip 17 | 'port' => 7001, //socket 监听端口 18 | 'server_type' => Swoole::TYPE_TCP, //socket 业务模型 tcp/udp/http/websocket 19 | 'daemonize' => 1, //是否开启守护进程 20 | 'work_mode' => 3, //工作模式:1:单进程单线程 2:多线程 3: 多进程 21 | 'worker_num' => 32, //工作进程数 22 | 'task_worker_num' => 32, //工作进程数 23 | 'max_request' => 0, //单个进程最大处理请求数 24 | 'addlisten' => array( //开启udp监听 25 | 'ip' => '0.0.0.0', 26 | 'port' => 7011 27 | ), 28 | ), 29 | ); 30 | -------------------------------------------------------------------------------- /ant-example/user-center/config/socket/register.php: -------------------------------------------------------------------------------- 1 | array( 4 | 'ip' => '10.94.107.22', 5 | 'port' => 9949, 6 | ), 7 | ); -------------------------------------------------------------------------------- /ant-example/user-center/webroot/main.php: -------------------------------------------------------------------------------- 1 | | 14 | +----------------------------------------------------------------------+ 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include "PHP_API.hpp" 21 | #include "module.h" 22 | 23 | using namespace std; 24 | using namespace PHP; 25 | 26 | extern "C" 27 | { 28 | int swModule_init(swModule *); 29 | } 30 | 31 | Variant MessagePacker_construct(Object &_this, string &data); 32 | Variant MessagePacker_resetForUnPack(Object &_this, string &data); 33 | Variant MessagePacker_resetForPack(Object &_this); 34 | Variant MessagePacker_resetOffset(Object &_this, int &len); 35 | Variant MessagePacker_writeString(Object &_this, string &data, int &len); 36 | Variant MessagePacker_writeBool(Object &_this, char b); 37 | Variant MessagePacker_writeInt(Object &_this, int &i); 38 | Variant MessagePacker_writeInt16(Object &_this, short &i); 39 | Variant MessagePacker_readByte(Object &_this); 40 | Variant MessagePacker_readInt(Object &_this); 41 | Variant MessagePacker_readInt16(Object &_this); 42 | Variant MessagePacker_readString(Object &_this); 43 | Variant MessagePacker_readBinary(Object &_this); 44 | Variant MessagePacker_readBool(Object &_this); 45 | Variant MessagePacker_getData(Object &_this); 46 | Variant MessagePacker_getBuffer(Object &_this); 47 | Variant MessagePacker_isEnd(Object &_this); 48 | static char[4] itoc(int i) 49 | { 50 | bt = char[4]; 51 | bt[0] = i && 0xff; 52 | bt[1] = i >> 8 && 0xff; 53 | bt[2] = i >> 16 && 0xff; 54 | bt[3] = i >> 24 && 0xff; 55 | return bt; 56 | } 57 | static int ctoi(char* _data) 58 | { 59 | int ret = -1; 60 | ret = _data[0] & 0xff; 61 | ret |= ((_data[1] << 8) & 0xff00); 62 | ret |= ((_data[2] << 16) & 0xff0000); 63 | ret |= ((_data[3] << 24) & 0xff000000); 64 | return ret; 65 | } 66 | 67 | int swModule_init(swModule *module) 68 | { 69 | module->name = (char *) "MessagePacker"; 70 | 71 | Class c("MessagePacker"); 72 | c.addProperty("data", ""); 73 | c.addProperty("offset", 0); 74 | c.addProperty("dataLen", 0); 75 | c.addMethod("__construct", MessagePacker_construct, CONSTRUCT); 76 | c.addMethod("resetForUnPack", MessagePacker_resetForUnPack); 77 | c.addMethod("resetForPack", MessagePacker_resetForPack); 78 | c.addMethod("resetOffset", MessagePacker_resetOffset); 79 | c.addMethod("writeByte", MessagePacker_writeByte); 80 | c.addMethod("writeString", MessagePacker_writeString); 81 | c.addMethod("writeBinary", MessagePacker_writeBinary); 82 | c.addMethod("writeBool", MessagePacker_writeBool); 83 | c.addMethod("writeInt", MessagePacker_writeInt); 84 | c.addMethod("writeInt16", MessagePacker_writeInt16); 85 | c.addMethod("readByte", MessagePacker_readByte); 86 | c.addMethod("readInt", MessagePacker_readInt); 87 | c.addMethod("readInt16", MessagePacker_readInt16); 88 | c.addMethod("readString", MessagePacker_readString); 89 | c.addMethod("readBinary", MessagePacker_readBinary); 90 | c.addMethod("readBool", MessagePacker_readBool); 91 | c.addMethod("getData", MessagePacker_getData); 92 | c.addMethod("getBuffer", MessagePacker_getBuffer); 93 | c.addMethod("isEnd", MessagePacker_isEnd); 94 | c.activate(); 95 | return SW_OK; 96 | } 97 | 98 | Variant MessagePacker_construct(Object &_this, char* &data) 99 | { 100 | _this.set("data", data); 101 | _this.set("dataLen", strlen(data)); 102 | return nullptr; 103 | } 104 | Variant MessagePacker_resetForUnPack(Object &_this, char* &data) 105 | { 106 | _this.set("data", data); 107 | _this.set("dataLen", strlen(data)); 108 | _this.set("offset", 0); 109 | return nullptr; 110 | } 111 | 112 | Variant MessagePacker_resetForPack(Object &_this) 113 | { 114 | _this.set("data", ""); 115 | _this.set("dataLen", 0); 116 | _this.set("offset", 0); 117 | return nullptr; 118 | } 119 | 120 | Variant MessagePacker_resetOffset(Object &_this) 121 | { 122 | _this.set("offset", 0); 123 | return nullptr; 124 | } 125 | 126 | Variant MessagePacker_writeByte(Object &_this, char &b) 127 | { 128 | Variant data = _this.get("data"); 129 | _this.set("data", (data.toString() + string(b, 1)).c_str()); 130 | Variant dataLen = _this.get("dataLen"); 131 | _this.set("dataLen", dataLen.toInt() + 1); 132 | return nullptr; 133 | } 134 | 135 | Variant MessagePacker_writeString(Object &_this, string &str) 136 | { 137 | Variant data = _this.get("data"); 138 | _this.set("data", (data.toString() + str).c_str()); 139 | Variant dataLen = _this.get("dataLen"); 140 | _this.set("dataLen", dataLen.toInt() + str.length()); 141 | return nullptr; 142 | } 143 | 144 | Variant MessagePacker_writeString(Object &_this, uint8 &bool) 145 | { 146 | Variant data = _this.get("data"); 147 | _this.set("data", (data.toString() + string(bool, 1)).c_str()); 148 | Variant dataLen = _this.get("dataLen"); 149 | _this.set("dataLen", dataLen.toInt() + 1); 150 | return nullptr; 151 | } 152 | 153 | Variant MessagePacker_writeInt(Object &_this, int &i) 154 | { 155 | Variant data = _this.get("data"); 156 | bt = itoc(i); 157 | _this.set("data", (data.toString() + string(bt, 4)).c_str()); 158 | Variant dataLen = _this.get("dataLen"); 159 | _this.set("dataLen", dataLen.toInt() + 4); 160 | return nullptr; 161 | } 162 | 163 | 164 | Variant MessagePacker_writeInt16(Object &_this, int &i) 165 | { 166 | Variant data = _this.get("data"); 167 | bt = char[2]; 168 | bt[0] = i && 0xff; 169 | bt[1] = i >> 8 && 0xff; 170 | _this.set("data", (data.toString() + string(bt, 2)).c_str()); 171 | Variant dataLen = _this.get("dataLen"); 172 | _this.set("dataLen", dataLen.toInt() + 2); 173 | return nullptr; 174 | } 175 | 176 | Variant MessagePacker_readByte(Object &_this) 177 | { 178 | Variant data = _this.get("data"); 179 | Variant offset = _this.get("offset"); 180 | char * _data = data.toCString(); 181 | int _offset = offset.toInt(); 182 | _data+=offset; 183 | offset+=1 184 | return _data[0]; 185 | } 186 | 187 | Variant MessagePacker_readBool(Object &_this) 188 | { 189 | Variant data = _this.get("data"); 190 | Variant offset = _this.get("offset"); 191 | char * _data = data.toCString(); 192 | int _offset = offset.toInt(); 193 | _data+=offset; 194 | offset+=1 195 | return _data[0]; 196 | } 197 | 198 | Variant MessagePacker_readInt(Object &_this) 199 | { 200 | Variant data = _this.get("data"); 201 | Variant offset = _this.get("offset"); 202 | char * _data = data.toCString(); 203 | int _offset = offset.toInt(); 204 | _data+=offset; 205 | offset+=4; 206 | return ctoi(_data); 207 | } 208 | 209 | Variant MessagePacker_readString(Object &_this) 210 | { 211 | Variant data = _this.get("data"); 212 | Variant offset = _this.get("offset"); 213 | char * _data = data.toCString(); 214 | int _offset = offset.toInt(); 215 | _data+=offset; 216 | offset+=1; 217 | return _data; 218 | } 219 | 220 | Variant MessagePacker_readBinary(Object &_this) 221 | { 222 | Variant data = _this.get("data"); 223 | Variant offset = _this.get("offset"); 224 | char * _data = data.toCString(); 225 | int _offset = offset.toInt(); 226 | _data+=offset; 227 | offset+=1; 228 | return _data[0]; 229 | } 230 | 231 | 232 | 233 | 234 | -------------------------------------------------------------------------------- /ant-lib/common/Consts.php: -------------------------------------------------------------------------------- 1 | init(); 30 | } 31 | return $dao; 32 | } 33 | } -------------------------------------------------------------------------------- /ant-lib/common/Log.php: -------------------------------------------------------------------------------- 1 | 0) { 23 | return current($localIps); 24 | } 25 | return null; 26 | } 27 | 28 | public static function getServiceConfigNamespace($serviceName) 29 | { 30 | return '_'.$serviceName.'_config_'; 31 | } 32 | } -------------------------------------------------------------------------------- /ant-lib/common/VaildInput.php: -------------------------------------------------------------------------------- 1 | 1) { 50 | $filter = explode('-', substr($type, 1)); 51 | } else { 52 | $filter = [0, 0]; 53 | } 54 | return self::int($str, intval($filter[0]), intval($filter[1]), $errmsg); 55 | break; 56 | case 'f': //浮点数字 57 | if (strlen($type) > 1) { 58 | $filter = explode('-', substr($type, 1)); 59 | } else { 60 | $filter = [0, 0]; 61 | } 62 | return self::float($str, intval($filter[0]), intval($filter[1]), $errmsg); 63 | break; 64 | case 's': //字符串 smin-max 65 | if (strlen($type) > 1) { 66 | $filter = explode('-', substr($type, 1)); 67 | } else { 68 | $filter = [0, 0]; 69 | } 70 | return self::string($str, intval($filter[0]), intval($filter[1]), $errmsg); 71 | break; 72 | case 'n': //字母开头,只包含字母,数字 -_ 73 | if (strlen($type) > 1) { 74 | $filter = explode('-', substr($type, 1)); 75 | } else { 76 | $filter = [0, 0]; 77 | } 78 | return self::username($str, intval($filter[0]), intval($filter[1]), $errmsg); 79 | break; 80 | case 'c': //只匹配中文 81 | $filter = explode('-', substr($type, 1)); 82 | return self::chinese($str, intval($filter[0]), intval($filter[1]), $errmsg); 83 | break; 84 | case 'g': //包含中文 85 | return self::hasChinese($str, $errmsg); 86 | break; 87 | case 'p': //匹配ip 88 | return self::ip($str, $errmsg); 89 | break; 90 | case 'a': //匹配mac地址 91 | return self::mac($str, $errmsg); 92 | break; 93 | default: //默认按正则 94 | return self::regexp($str, $type, $errmsg); 95 | break; 96 | } 97 | } 98 | 99 | /** 100 | * @param $email 101 | * @param string $errmsg 102 | * @return mixed 103 | * @throws InputVaildException 104 | */ 105 | public static function email($email, $errmsg = '') 106 | { 107 | $ret = filter_var($email, FILTER_VALIDATE_EMAIL); 108 | if (false === $ret) { 109 | $errmsg = $errmsg ? $errmsg : '错误的email格式'; 110 | throw new InputVaildException($errmsg); 111 | } 112 | 113 | return $ret; 114 | } 115 | 116 | /** 117 | * @param $url 118 | * @param string $errmsg 119 | * @return mixed 120 | * @throws InputVaildException 121 | */ 122 | public static function url($url, $errmsg = '') 123 | { 124 | $ret = filter_var($url, FILTER_VALIDATE_URL); 125 | if (false === $ret) { 126 | $errmsg = $errmsg ? $errmsg : '错误的url格式'; 127 | throw new InputVaildException($errmsg); 128 | } 129 | 130 | return $ret; 131 | } 132 | 133 | /** 134 | * @param $ip 135 | * @param string $errmsg 136 | * @return mixed 137 | * @throws InputVaildException 138 | */ 139 | public static function ip($ip, $errmsg = '') 140 | { 141 | $ret = filter_var($ip, FILTER_VALIDATE_IP); 142 | if (false === $ret) { 143 | $errmsg = $errmsg ? $errmsg : '错误的ip格式'; 144 | throw new InputVaildException($errmsg); 145 | } 146 | 147 | return $ret; 148 | } 149 | 150 | /** 151 | * @param $int 152 | * @param int $min 153 | * @param int $max 154 | * @param string $errmsg 155 | * @return mixed 156 | * @throws InputVaildException 157 | */ 158 | public static function int($int, $min = 0, $max = 0, $errmsg = '') 159 | { 160 | $options = []; 161 | if ($min) { 162 | $options['min_range'] = $min; 163 | } 164 | if ($max) { 165 | $options['min_range'] = $max; 166 | } 167 | $ret = filter_var($int, FILTER_VALIDATE_INT, [ 168 | 'options' => $options 169 | ]); 170 | if (false === $ret) { 171 | $errmsg = $errmsg ? $errmsg : '错误的数字格式'; 172 | throw new InputVaildException($errmsg); 173 | } 174 | 175 | return $ret; 176 | } 177 | 178 | /** 179 | * @param $float 180 | * @param int $min 181 | * @param int $max 182 | * @param string $errmsg 183 | * @return mixed 184 | * @throws InputVaildException 185 | */ 186 | public static function float($float, $min = 0, $max = 0, $errmsg = '') 187 | { 188 | $options = []; 189 | if ($min) { 190 | $options['min_range'] = $min; 191 | } 192 | if ($max) { 193 | $options['min_range'] = $max; 194 | } 195 | $ret = filter_var($float, FILTER_VALIDATE_FLOAT, [ 196 | 'options' => $options 197 | ]); 198 | if (false === $ret) { 199 | $errmsg = $errmsg ? $errmsg : '错误的数字格式'; 200 | throw new InputVaildException($errmsg); 201 | } 202 | 203 | return $ret; 204 | } 205 | 206 | /** 207 | * @param $str 208 | * @param $regexp 209 | * @param string $errmsg 210 | * @return mixed 211 | * @throws InputVaildException 212 | */ 213 | public static function regexp($str, $regexp, $errmsg = '') 214 | { 215 | $ret = filter_var($str, FILTER_VALIDATE_REGEXP, [ 216 | 'options' => [ 217 | 'regexp' => $regexp 218 | ] 219 | ]); 220 | if (false === $ret) { 221 | $errmsg = $errmsg ? $errmsg : '错误的格式'; 222 | throw new InputVaildException($errmsg); 223 | } 224 | return $ret; 225 | } 226 | 227 | /** 228 | * @param $str 229 | * @param string $errmsg 230 | * @return mixed 231 | * @throws InputVaildException 232 | */ 233 | public static function mac($str, $errmsg = '') 234 | { 235 | $ret = filter_var($str, FILTER_VALIDATE_MAC); 236 | if (false === $ret) { 237 | $errmsg = $errmsg ? $errmsg : '错误mac地址的格式'; 238 | throw new InputVaildException($errmsg); 239 | } 240 | return $ret; 241 | } 242 | 243 | /** 244 | * @param $mobileNum 245 | * @param string $errmsg 246 | * @return mixed 247 | * @throws InputVaildException 248 | */ 249 | public static function mobile($mobileNum, $errmsg = '') 250 | { 251 | $errmsg = $errmsg ? $errmsg : '错误的手机号码'; 252 | return self::regexp($mobileNum, '/1{1}\d{10}$/', $errmsg); 253 | } 254 | 255 | ///^[a-zA-Z][a-zA-Z0-9-_]{3,16}$/ 256 | public static function username($str, $min = 1, $max = 50, $errmsg = '') 257 | { 258 | $errmsg = $errmsg ? $errmsg : "必需以字母开头且长度在{$min}-{$max}之间"; 259 | return self::regexp($str, '/^[a-zA-Z][a-zA-Z0-9-_\-]{' . $min . ',' . $max . '}$/', $errmsg); 260 | } 261 | 262 | /** 263 | * @param $str 264 | * @param int $min 265 | * @param int $max 266 | * @param string $errmsg 267 | * @return mixed 268 | * @throws InputVaildException 269 | */ 270 | public static function string($str, $min = 1, $max = 50, $errmsg = '') 271 | { 272 | $ret = filter_var($str, FILTER_SANITIZE_STRING, FILTER_FLAG_ENCODE_LOW | FILTER_FLAG_ENCODE_AMP); 273 | if ($ret == false) { 274 | $errmsg = $errmsg ? $errmsg : '错误输入格式'; 275 | throw new InputVaildException($errmsg); 276 | } 277 | 278 | if ($min && strlen($ret) < $min) { 279 | throw new InputVaildException('至少' . $min . '个字符'); 280 | } 281 | 282 | if ($max && strlen($ret) > $max) { 283 | throw new InputVaildException('至多' . $max . '个字符'); 284 | } 285 | 286 | return $ret; 287 | } 288 | 289 | /** 290 | * @param $str 291 | * @param int $min 292 | * @param int $max 293 | * @param $errmsg 294 | * @return mixed 295 | * @throws InputVaildException 296 | */ 297 | public static function chinese($str, $min = 1, $max = 50, $errmsg) 298 | { 299 | $errmsg = $errmsg ? $errmsg : '必需为中文'; 300 | $ret = self::regexp($str, '/^[\x{4e00}-\x{9fa5}]+$/u', $errmsg); 301 | if ($min && mb_strlen($ret) < $min) { 302 | $errmsg = '至少' . $min . '个汉字'; 303 | throw new InputVaildException($errmsg); 304 | } 305 | 306 | if ($max && mb_strlen($ret) > $max) { 307 | $errmsg = '至多' . $max . '个汉字'; 308 | throw new InputVaildException($errmsg); 309 | } 310 | 311 | return $ret; 312 | } 313 | 314 | /** 315 | * @param $str 316 | * @param string $errmsg 317 | * @return mixed 318 | * @throws InputVaildException 319 | */ 320 | public static function hasChinese($str, $errmsg = '') 321 | { 322 | $errmsg = $errmsg ? $errmsg : '必需包含为中文'; 323 | return self::regexp($str, '/[^\x00-\x80]/', $errmsg); 324 | } 325 | } -------------------------------------------------------------------------------- /ant-lib/config/README.md: -------------------------------------------------------------------------------- 1 | 存在服务列表配置 2 | 命名:serviceName.php -------------------------------------------------------------------------------- /ant-lib/ctrl/Base.php: -------------------------------------------------------------------------------- 1 | _filter($_POST); 26 | } 27 | if (!empty($_GET)) { 28 | $_GET = $this->_filter($_GET); 29 | } 30 | $params = Request::getParams(); 31 | if (!empty($params)) { 32 | $params = $this->_filter($params); 33 | $_REQUEST = $params; 34 | Request::setParams($params); 35 | } 36 | //数据库的超时检测 37 | common\LoadClass::getDao('Auto')->checkPing(); 38 | return true; 39 | } 40 | 41 | private function _filter($params) 42 | { 43 | foreach ($params as &$val) { 44 | if (is_array($val)) { 45 | $val = $this->_filter($val); 46 | } else { 47 | $val = addslashes(trim($val)); 48 | } 49 | } 50 | unset($val); 51 | return $params; 52 | } 53 | 54 | /** 55 | * @return array 56 | * @desc 后置控制器 57 | */ 58 | public function _after() 59 | { 60 | } 61 | 62 | /** 63 | * @param $key 参数名 64 | * @param null $default 当没有此参数时的默认值 65 | * @param array|null $params 数据源(默认 Request::getParams()) 66 | * @param bool|false $abs 是否取绝对值 67 | * @param bool|false $notEmpty 是否能为空 68 | * @return int|null|number 69 | * @throws ParamException 70 | * @desc 获取int型参数 71 | */ 72 | protected function getInteger($key, $default = null, array $params = null, $abs = false, $notEmpty = false) 73 | { 74 | if (empty($params)) { 75 | $params = Request::getParams(); 76 | } 77 | if (!isset($params[$key])) { 78 | if (isset($params[$key])) { 79 | return \intval($params[$key]); 80 | } 81 | if ($default !== null) { 82 | return $default; 83 | } 84 | throw new ParamException("no params {$key}", common\ERROR::PARAM_ERROR); 85 | } 86 | $integer = isset($params[$key]) ? \intval($params[$key]) : 0; 87 | if ($abs) { 88 | $integer = \abs($integer); 89 | } 90 | if ($notEmpty && empty($integer)) { 91 | throw new ParamException('params no empty', common\ERROR::PARAM_ERROR); 92 | } 93 | return $integer; 94 | } 95 | 96 | /** 97 | * @param $key 参数名 98 | * @param null $default 当没有此参数时的默认值 99 | * @param array|null $params 数据源(默认 Request::getParams()) 100 | * @param bool|false $abs 是否取绝对值 101 | * @param bool|false $notEmpty 是否能为空 102 | * @return int|null|number 103 | * @throws ParamException 104 | * @desc 获取浮点型参数 105 | */ 106 | protected function getFloat($key, $default = null, array $params = null, $abs = true, $notEmpty = false) 107 | { 108 | if (empty($params)) { 109 | $params = Request::getParams(); 110 | } 111 | if (empty($params[$key])) { 112 | if (isset($params[$key])) { 113 | return \floatval($params[$key]); 114 | } 115 | if ($default !== null) { 116 | return $default; 117 | } 118 | throw new ParamException("no params {$key}", common\ERROR::PARAM_ERROR); 119 | } 120 | $integer = isset($params[$key]) ? \floatval($params[$key]) : 0; 121 | if ($abs) { 122 | $integer = \abs($integer); 123 | } 124 | if ($notEmpty && empty($integer)) { 125 | throw new ParamException('params no empty', common\ERROR::PARAM_ERROR); 126 | } 127 | return $integer; 128 | } 129 | 130 | /** 131 | * @param $key 参数名 132 | * @param null $default 当没有此参数时的默认值 133 | * @param array|null $params 数据源(默认 Request::getParams()) 134 | * @param bool|false $notEmpty 是否能为空 135 | * @return int|null|number 136 | * @throws ParamException 137 | * @desc 获取字符串参数 138 | */ 139 | protected function getString($key, $default = null, array $params = null, $notEmpty = true) 140 | { 141 | if (empty($params)) { 142 | $params = Request::getParams(); 143 | } 144 | if (empty($params[$key])) { 145 | if (null !== $default) { 146 | return $default; 147 | } 148 | throw new ParamException("no params {$key}", common\ERROR::PARAM_ERROR); 149 | } 150 | $string = $params[$key]; 151 | if (!empty($notEmpty) && empty($string)) { 152 | throw new ParamException('params no empty', common\ERROR::PARAM_ERROR); 153 | } 154 | return $string; 155 | } 156 | 157 | /** 158 | * @param $key 159 | * @param null $default 160 | * @param array|null $params 161 | * @param bool|true $notEmpty 162 | * @return array|null 163 | * @throws ParamException 164 | * @desc 获取数组类型的参数 165 | */ 166 | protected function getArray($key, $default = null, array $params = null, $notEmpty = true) 167 | { 168 | if (empty($params)) { 169 | $params = Request::getParams(); 170 | } 171 | if (empty($params[$key])) { 172 | if (isset($params[$key])) { 173 | return []; 174 | } 175 | if (null !== $default) { 176 | return $default; 177 | } 178 | throw new ParamException("no params {$key}", common\ERROR::PARAM_ERROR); 179 | } 180 | $data = $params[$key]; 181 | if (!empty($notEmpty) && empty($data)) { 182 | throw new ParamException('params no empty', common\ERROR::PARAM_ERROR); 183 | } 184 | return $data; 185 | } 186 | 187 | /** 188 | * @param $key 189 | * @param null $default 190 | * @param array|null $params 191 | * @param bool|true $notEmpty 192 | * @return mixed|null|string 193 | * @throws ParamException 194 | * @desc 获取json类型参数,转换为数组 195 | */ 196 | protected function getJson($key, $default = null, array $params = null, $notEmpty = true) 197 | { 198 | if (empty($params)) { 199 | $params = Request::getParams(); 200 | } 201 | if (empty($params[$key])) { 202 | if (isset($params[$key])) { 203 | return \trim($params[$key]); 204 | } 205 | if (null !== $default) { 206 | return $default; 207 | } 208 | throw new ParamException("no params {$key}", common\ERROR::PARAM_ERROR); 209 | } 210 | $data = \json_decode($params[$key], true); 211 | if (!empty($notEmpty) && empty($data)) { 212 | throw new ParamException('params no empty', common\ERROR::PARAM_ERROR); 213 | } 214 | return $data; 215 | } 216 | 217 | /** 218 | * @param array $data 219 | * @return array 220 | * @desc ctrl数据输出 221 | * 两个特殊变量 _view_mode: 强制指定view输出格式 (默认受 config中view_mode参数控制) 222 | * _tpl_file: 强制指定模版文件 (默认为 ctrl/method.php) 223 | */ 224 | protected function getView($data = array()) 225 | { 226 | $result = [ 227 | 'code' => 0, 228 | 'msg' => '', 229 | 'data' => $data, 230 | ]; 231 | if (Request::isAjax()) { 232 | $result['_view_mode'] = 'Json'; 233 | } 234 | return $result; 235 | } 236 | } 237 | -------------------------------------------------------------------------------- /ant-lib/ctrl/RestBase.php: -------------------------------------------------------------------------------- 1 | getJson('key', []); 22 | if (empty($key)) { 23 | return null; 24 | } 25 | LoadClass::getService('AntConfigAgent')->sync(ZConfig::getField('soa', 'serviceName'), $key); 26 | } 27 | 28 | public function remove() 29 | { 30 | $key = $this->getString('key'); 31 | if (empty($key)) { 32 | return null; 33 | } 34 | LoadClass::getService('AntConfigAgent')->remove(ZConfig::getField('soa', 'serviceName'), $key); 35 | } 36 | 37 | /** 38 | * @desc 配置同步 39 | */ 40 | public function syncAll() 41 | { 42 | LoadClass::getService('AntConfigAgent')->syncAll(ZConfig::getField('soa', 'serviceName')); 43 | } 44 | 45 | public function syncRegister() 46 | { 47 | $serviceInfo = $this->getJson('serviceInfo', []); 48 | if (!empty($serviceInfo)) { 49 | LoadClass::getService('AntConfigAgent')->syncRegister($serviceInfo); 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /ant-lib/dao/Auto.php: -------------------------------------------------------------------------------- 1 | entity = $entity; 35 | $this->_dbTag = $useDb; 36 | if ($entity && $useDb) { 37 | $this->init(); 38 | } 39 | } 40 | 41 | /** 42 | * @return null|ZPdo 43 | * @throws \Exception 44 | * @desc 使用db 45 | */ 46 | public function init() 47 | { 48 | if(!$this->_dbTag) { 49 | return null; 50 | } 51 | if (empty(self::$_dbs[$this->_dbTag])) { 52 | $config = ZConfig::getField('pdo', $this->_dbTag); 53 | self::$_dbs[$this->_dbTag] = new ZPdo($config, $this->entity, $config['dbname']); 54 | } 55 | $this->_db = self::$_dbs[$this->_dbTag]; 56 | $this->_db->setClassName($this->entity); 57 | $this->_db->checkPing(); 58 | return $this->_db; 59 | } 60 | 61 | /** 62 | * @param $tableName 63 | * @desc 更换表 64 | */ 65 | public function changeTable($tableName) 66 | { 67 | $this->_db->setTableName($tableName); 68 | } 69 | 70 | /** 71 | * @return bool 72 | * @desc 关闭db 73 | */ 74 | public function closeDb($tag = null) 75 | { 76 | if (empty($tag)) { 77 | $tag = $this->_dbTag; 78 | } 79 | if (empty($tag)) { 80 | return true; 81 | } 82 | if (empty($this->_db)) { 83 | return true; 84 | } 85 | $this->_db->close(); 86 | unset(self::$_dbs[$tag]); 87 | return true; 88 | } 89 | 90 | /** 91 | * @param $id 92 | * @return mixed 93 | * @throws \Exception 94 | * @desc 跟据 id 获取记录 95 | */ 96 | public function fetchById($id) 97 | { 98 | try { 99 | return $this->doResult($this->_db->fetchEntity("id={$id}")); 100 | } catch (\Exception $e) { 101 | Log::info([$this->_db->getLastSql()], 'sql_error'); 102 | throw $e; 103 | } 104 | } 105 | 106 | /** 107 | * @param $where 108 | * @param null $params 109 | * @param string $fields 110 | * @param null $orderBy 111 | * @return mixed 112 | * @throws \Exception 113 | */ 114 | public function fetchEntity($where, $params = null, $fields = '*', $orderBy = null) 115 | { 116 | try { 117 | return $this->doResult($this->_db->fetchEntity($this->parseWhere($where), $params, $fields, $orderBy)); 118 | } catch (\Exception $e) { 119 | Log::info([$this->_db->getLastSql()], 'sql_error'); 120 | throw $e; 121 | } 122 | } 123 | 124 | 125 | /** 126 | * @param array $items 127 | * @param null $params 128 | * @param string $fields 129 | * @param null $orderBy 130 | * @param null $limit 131 | * @return mixed 132 | * @throws \Exception 133 | * @desc 多行记录获取 134 | */ 135 | public function fetchAll(array $items = [], $params = null, $fields = '*', $orderBy = null, $limit = null) 136 | { 137 | try { 138 | return $this->doResult($this->_db->fetchAll($this->parseWhere($items), $params, $fields, $orderBy, $limit)); 139 | } catch (\Exception $e) { 140 | Log::info([$this->_db->getLastSql()], 'sql_error'); 141 | throw $e; 142 | } 143 | } 144 | 145 | /** 146 | * @param $items 147 | * @return string 148 | * @desc 解析where 149 | */ 150 | private function parseWhere($items) 151 | { 152 | 153 | if (empty($items)) { 154 | return 1; 155 | } 156 | 157 | if (is_string($items)) { 158 | return $items; 159 | } 160 | 161 | $where = '1'; 162 | 163 | if (!empty($items['union'])) { 164 | foreach ($items['union'] as $union) { 165 | $where .= " {$union}"; 166 | } 167 | unset($items['union']); 168 | } 169 | 170 | foreach ($items as $k => $v) { 171 | $where .= " AND {$k} {$v}"; 172 | } 173 | 174 | return $where; 175 | } 176 | 177 | /** 178 | * @param string $where 179 | * @return mixed 180 | * @throws \Exception 181 | */ 182 | public function fetchWhere($where = '') 183 | { 184 | try { 185 | return $this->doResult($this->_db->fetchAll($this->parseWhere($where))); 186 | } catch (\Exception $e) { 187 | Log::info([$this->_db->getLastSql()], 'sql_error'); 188 | throw $e; 189 | } 190 | } 191 | 192 | /** 193 | * @param $attr 194 | * @param array $items 195 | * @param int $change 196 | * @return mixed 197 | * @throws \Exception 198 | */ 199 | public function update($attr, $items = [], $change = 0) 200 | { 201 | if (empty($attr)) { 202 | $attr = new $this->entity; 203 | $attr->create(); 204 | } 205 | 206 | $fields = array(); 207 | $params = array(); 208 | if (is_object($attr)) { 209 | foreach ($attr->getFields() as $key) { 210 | $fields[] = $key; 211 | $params[$key] = $attr->$key; 212 | } 213 | } else { 214 | $fields = array_keys($attr); 215 | $params = $attr; 216 | } 217 | 218 | if (!empty($items)) { 219 | $where = $this->parseWhere($items); 220 | } else { 221 | $pkid = $attr::PK_ID; 222 | $where = "`{$pkid}`=" . $attr->$pkid; 223 | } 224 | 225 | try { 226 | return $this->doResult($this->_db->update($fields, $params, $where, $change)); 227 | } catch (\Exception $e) { 228 | Log::info([$this->_db->getLastSql()], 'sql_error'); 229 | throw $e; 230 | } 231 | } 232 | 233 | /** 234 | * @param $attr 235 | * @return mixed 236 | * @throws \Exception 237 | */ 238 | public function add($attr) 239 | { 240 | if (empty($attr) || is_array($attr)) { 241 | $entity = new $this->entity; 242 | $entity->create($attr); 243 | } elseif (is_object($attr)) { 244 | $entity = $attr; 245 | } 246 | try { 247 | return $this->doResult($this->_db->add($entity, $entity->getFields())); 248 | } catch (\Exception $e) { 249 | Log::info([$this->_db->getLastSql()], 'sql_error'); 250 | throw $e; 251 | } 252 | } 253 | 254 | /** 255 | * @param $where 256 | * @return mixed 257 | * @throws DaoException 258 | * @throws \Exception 259 | */ 260 | public function remove($where) 261 | { 262 | if (empty($where)) { 263 | throw new DaoException('remove where empty', ERROR::REMOVE_WHERE_EMPTY); 264 | } 265 | 266 | try { 267 | return $this->doResult($this->_db->remove($this->parseWhere($where))); 268 | } catch (\Exception $e) { 269 | Log::info([$this->_db->getLastSql()], 'sql_error'); 270 | throw $e; 271 | } 272 | } 273 | 274 | 275 | /** 276 | * @param array $items 277 | * @param string $fields 278 | * @param null $orderBy 279 | * @param null $start 280 | * @param null $limit 281 | * @return mixed 282 | * @throws \Exception 283 | */ 284 | public function fetchArray(array $items = [], $fields = "*", $orderBy = null, $start = null, $limit = null) 285 | { 286 | try { 287 | if (empty($items)) { 288 | return $this->doResult($this->_db->fetchArray(1, $fields, $orderBy, $start, $limit)); 289 | } 290 | return $this->doResult($this->_db->fetchArray($this->parseWhere($items), $fields, $orderBy, $start, $limit)); 291 | } catch (\Exception $e) { 292 | Log::info([$this->_db->getLastSql()], 'sql_error'); 293 | throw $e; 294 | } 295 | } 296 | 297 | /** 298 | * @param array $items 299 | * @return mixed 300 | * @throws \Exception 301 | */ 302 | public function fetchCount($items = []) 303 | { 304 | try { 305 | return $this->doResult($this->_db->fetchCount($this->parseWhere($items))); 306 | } catch (\Exception $e) { 307 | Log::info([$this->_db->getLastSql()], 'sql_error'); 308 | throw $e; 309 | } 310 | } 311 | 312 | /** 313 | * @param array $items 314 | * @param string $fields 315 | * @return mixed 316 | * @throws \Exception 317 | */ 318 | public function fetchOne($items = [], $fields = "*") 319 | { 320 | try { 321 | return $this->doResult($this->_db->fetchEntity($this->parseWhere($items), null, $fields)); 322 | } catch (\Exception $e) { 323 | Log::info([$this->_db->getLastSql()], 'sql_error'); 324 | throw $e; 325 | } 326 | } 327 | 328 | /** 329 | * @param array $items 330 | * @return mixed 331 | * @throws \Exception 332 | */ 333 | public function fetchByUnion($items = []) 334 | { 335 | $fields = ""; 336 | $tables = ""; 337 | $dbname = ZConfig::getField('pdo', $this->_dbTag, 'dbname'); 338 | foreach ($items['fields'] as $table => $fieldArr) { 339 | foreach ($fieldArr as $field) { 340 | $fields .= "{$table}.{$field},"; 341 | } 342 | $tables .= "{$dbname}.$table,"; 343 | } 344 | $fields = rtrim($fields, ','); 345 | $tables = rtrim($tables, ','); 346 | $wheres = "1"; 347 | 348 | foreach ($items['where'] as $item) { 349 | $wheres .= " and " . $item; 350 | } 351 | 352 | $order = ""; 353 | if (!empty($items['order'])) { 354 | $order = $items['order']; 355 | } 356 | 357 | $sql = "select {$fields} from {$tables} where {$wheres}{$order}"; 358 | 359 | try { 360 | return $this->doResult($this->fetchBySql($sql)); 361 | } catch (\Exception $e) { 362 | Log::info([$this->_db->getLastSql()], 'sql_error'); 363 | throw $e; 364 | } 365 | } 366 | 367 | /** 368 | * @param $sql 369 | * @return mixed 370 | * @throws \Exception 371 | */ 372 | public function fetchBySql($sql) 373 | { 374 | try { 375 | return $this->doResult($this->_db->fetchBySql($sql)); 376 | } catch (\Exception $e) { 377 | Log::info([$this->_db->getLastSql()], 'sql_error'); 378 | throw $e; 379 | } 380 | } 381 | 382 | /** 383 | * @param $result 384 | * @return mixed 385 | */ 386 | private function doResult($result) 387 | { 388 | Log::info([$this->_db->getLastSql()], 'sql'); 389 | return $result; 390 | } 391 | 392 | /** 393 | * 394 | */ 395 | public function checkPing() 396 | { 397 | if (!empty(self::$_dbs)) { 398 | foreach (self::$_dbs as $db) { 399 | $db->checkPing(); 400 | } 401 | } 402 | } 403 | 404 | } -------------------------------------------------------------------------------- /ant-lib/entity/Base.php: -------------------------------------------------------------------------------- 1 | 8 | * @copyright 2013 - 2017 ZPHP Co. 9 | * @license PHP 10 | * @link zphp.com 11 | * @category 12 | * 13 | */ 14 | namespace entity; 15 | 16 | use common\VaildInput; 17 | 18 | abstract class Base 19 | { 20 | private $_add_fields = []; 21 | private $_create = 1; 22 | /** 23 | * 表单验证规则数组 24 | * 25 | * @var array 26 | */ 27 | protected $_vaild = []; 28 | 29 | 30 | /** 31 | * @param array $data 32 | * @return bool 33 | * @throws \exceptionHandler\InputVaildException 34 | * @desc 自动填充表单 35 | */ 36 | public function create($data = array()) 37 | { 38 | if (empty($this->_create)) { 39 | return false; 40 | } 41 | 42 | if (empty($data)) { 43 | $data = $this->getPost(); 44 | } 45 | $this->_add_fields = array(); 46 | foreach ($data as $key => $val) { 47 | if (property_exists($this, $key)) { 48 | if (isset($this->_vaild[$key])) { 49 | $val = VaildInput::vaild($val, $this->_vaild[$key]); 50 | } 51 | $this->$key = $val; 52 | $this->_add_fields[] = $key; 53 | } 54 | } 55 | } 56 | 57 | /** 58 | * A summary 不自动创建 59 | * A *description* 60 | * 61 | * @return void 62 | */ 63 | public function noCreate() 64 | { 65 | $this->_create = 0; 66 | } 67 | 68 | /** 69 | * 获取字段列表 70 | * 71 | * @return array 72 | */ 73 | public function getFields() 74 | { 75 | if (!empty($this->_add_fields)) { 76 | return $this->_add_fields; 77 | } 78 | unset($this->_add_fields); 79 | unset($this->_create); 80 | unset($this->_vaild); 81 | return \array_keys(\get_object_vars($this)); 82 | } 83 | 84 | /** 85 | * 获取主建名 86 | * 87 | * @return string 88 | */ 89 | public function getPkId() 90 | { 91 | return self::PK_ID; 92 | } 93 | 94 | /** 95 | * 获取表单post数组 96 | * 97 | * @return array 98 | */ 99 | public function getPost() 100 | { 101 | return $_POST; 102 | } 103 | } -------------------------------------------------------------------------------- /ant-lib/exceptionHandler/BaseException.php: -------------------------------------------------------------------------------- 1 | realCode = $code; 29 | parent::__construct($message, $code); 30 | self::$exceptions[] = $this; 31 | } 32 | 33 | /** 34 | * @return int 35 | * @desc 获取执行过程中的异常发生次数 36 | */ 37 | public static function getExceptionNum() 38 | { 39 | return \count(self::$exceptions); 40 | } 41 | 42 | /** 43 | * @return BaseException|null 44 | * @desc 获取执行过程中的发生的最后一次异常 45 | */ 46 | public static function getLastException() 47 | { 48 | return empty(self::$exceptions) ? null : \end(self::$exceptions); 49 | } 50 | 51 | /** 52 | * @return mixed 53 | * @desc 移动最后一个异常 54 | */ 55 | public static function removeLast() 56 | { 57 | return \array_pop(self::$exceptions); 58 | } 59 | 60 | /** 61 | * @param $exception 62 | * @return mixed 63 | * @throws \Exception 64 | * @desc 异常处理 handler 65 | */ 66 | public static function exceptionHandler($exception) 67 | { 68 | $class = get_class($exception); 69 | if (__CLASS__ == $class && 70 | empty($exception->_child) && 71 | method_exists($exception, 'exceptionHandler')) { 72 | $exception->_child = 1; 73 | return call_user_func([$exception, 'exceptionHandler'], $exception); 74 | } else { 75 | $config = ZConfig::get('project'); 76 | $model = ZFormater::exception($exception); 77 | Log::info([\var_export($model, true)], $class); 78 | 79 | $info = array(); 80 | if (!empty($exception->realCode)) { 81 | $codeArr = explode('_', $exception->realCode); 82 | if (count($codeArr) > 1) { 83 | $model['code'] = intval($codeArr[0]); 84 | $model['message'] = $codeArr[1]; 85 | } 86 | } 87 | if ($config['debug_mode']) { 88 | $info['debug'] = $model; 89 | } 90 | $info['msg'] = $model['message']; 91 | $info['code'] = $model['code']; 92 | return self::display($info, $config['debug_mode']); 93 | } 94 | } 95 | 96 | /** 97 | * @return mixed 98 | * @throws \Exception 99 | * @desc fatal error处理 100 | */ 101 | public static function fatalHandler() 102 | { 103 | $error = \error_get_last(); 104 | if (empty($error)) { 105 | return true; 106 | } 107 | if (!in_array($error['type'], array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR))) { 108 | return true; 109 | } 110 | $config = ZConfig::get('project'); 111 | $model = ZFormater::fatal($error); 112 | if ($config['debug_mode']) { 113 | $info['debug'] = $model; 114 | $info['msg'] = $model['message']; 115 | } else { 116 | $info['msg'] = 'fatal error'; 117 | } 118 | Log::info([\var_export($model, true)], 'fatal'); 119 | $info['code'] = $model['code']; 120 | return self::display($info, $config['debug_mode']); 121 | } 122 | 123 | /** 124 | * @param $errno 125 | * @param $errstr 126 | * @param $errfile 127 | * @param $errline 128 | * @param $errcontext 129 | * @return int 130 | * @throws \Exception 131 | * @desc 一般错误处理 132 | */ 133 | public static function errorHandler($errno, $errstr, $errfile, $errline, $errcontext) 134 | { 135 | // if (!in_array($errno, [E_RECOVERABLE_ERROR, E_USER_ERROR])) { 136 | // return true; 137 | // } 138 | $error = [ 139 | 'type' => $errno, 140 | 'message' => $errstr, 141 | 'file' => $errfile, 142 | 'line' => $errline 143 | ]; 144 | $config = ZConfig::get('project'); 145 | $model = ZFormater::fatal($error, true, 'error'); 146 | if ($config['debug_mode']) { 147 | $model['errcontext'] = $errcontext; 148 | $info['debug'] = $model; 149 | } 150 | Log::info([\var_export($model, true)], 'php_error'); 151 | // $info['msg'] = $model['message']; 152 | // $info['code'] = $model['code']; 153 | // return self::display($info, $config['debug_mode']); 154 | return E_USER_ERROR; 155 | } 156 | 157 | /** 158 | * @param $info 159 | * @param bool $debug 160 | * @return mixed 161 | * @throws \Exception 162 | * @desc display输出 163 | */ 164 | protected static function display($info, $debug = false) 165 | { 166 | Response::status('200'); 167 | if ('Php' == Request::getViewMode()) { 168 | if ($debug) { 169 | Request::setTplFile('public/exception.php'); 170 | } else { 171 | Request::setTplFile('public/error.php'); 172 | } 173 | } 174 | $info['data'] = null; 175 | return Response::display($info); 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /ant-lib/exceptionHandler/ConfigException.php: -------------------------------------------------------------------------------- 1 | _sync($serviceName, $configData); 40 | } 41 | 42 | /** 43 | * @param $serviceName 44 | * @param $key 45 | * @return bool 46 | * @throws \Exception 47 | * @desc 删除某个配置 48 | */ 49 | public function remove($serviceName, $key) 50 | { 51 | if (empty($serviceName)) { 52 | return false; 53 | } 54 | $serviceName = Utils::getServiceConfigNamespace($serviceName); 55 | $configData = ZConfig::get($serviceName, []); 56 | if (isset($configData[$key])) { 57 | unset($configData[$key]); 58 | return $this->_sync($serviceName, $configData); 59 | } 60 | } 61 | 62 | /** 63 | * @param $serviceName 64 | * @return bool 65 | * @throws \Exception 66 | * @desc 清空所有的配置 67 | */ 68 | public function removeAll($serviceName) 69 | { 70 | if (empty($serviceName)) { 71 | return false; 72 | } 73 | $serviceName = Utils::getServiceConfigNamespace($serviceName); 74 | $configData = ZConfig::get($serviceName, []); 75 | if (!empty($configData)) { 76 | return $this->_sync($serviceName, []); 77 | } 78 | } 79 | 80 | /** 81 | * @param $serviceName 82 | * @return bool 83 | * @desc 服务启动时,进行全量同步 84 | */ 85 | public function syncAll($serviceName) 86 | { 87 | if (empty($serviceName)) { 88 | return false; 89 | } 90 | try { 91 | //同步服务配置 92 | $configService = LoadService::getService(Consts::CONFIG_SERVER_NAME); 93 | $result = $configService->call('all', [ 94 | 'serviceName' => $serviceName 95 | ]); 96 | if (empty($result)) { 97 | //读取数据失败 98 | return false; 99 | } 100 | $data = $result->getData(); 101 | if ($data && !empty($data['list'])) { 102 | $configData = []; 103 | foreach ($data['list'] as $_config) { 104 | $configData[$_config['item']] = is_array($_config['value']) ? $_config['value'] : json_decode($_config['value'], true); 105 | } 106 | $this->_sync(Utils::getServiceConfigNamespace($serviceName), $configData); 107 | } 108 | 109 | //同步服务列表 110 | $dir = ZPHP::getConfigPath() . DS . '..' . DS . 'public'; 111 | $fileList = Dir::tree($dir); 112 | if ($fileList) { 113 | foreach ($fileList as $file) { 114 | $filename = str_replace($dir . DS, '', $file); 115 | if (substr($filename, 0, 0) != 'service_') { //配置 116 | continue; 117 | } 118 | 119 | $serviceName = explode('.', $filename)[0]; 120 | if ($serviceName) { 121 | Scheduler::getListForRpc(str_replace('service_', '', $serviceName)); 122 | } 123 | } 124 | } 125 | return true; 126 | } catch (\Exception $e) { 127 | return false; 128 | } 129 | } 130 | 131 | /** 132 | * @param $serviceName 133 | * @param $data 134 | * @return bool 135 | * @desc 写入并更新配置文件 136 | */ 137 | private function _sync($serviceName, $data) 138 | { 139 | $path = ZPHP::getConfigPath() . DS . '..' . DS . 'public'; 140 | if (!is_dir($path)) { 141 | if (!mkdir($path)) { 142 | Log::info([$path], 'mkdir_error'); 143 | return false; 144 | } 145 | } 146 | $filename = $path . DS . $serviceName . '.php'; 147 | file_put_contents($filename, "" . var_export($data, true) . " 149 | );"); 150 | return ZConfig::mergeFile($filename); 151 | } 152 | 153 | 154 | /** 155 | * @param $serviceInfo 156 | * @throws \Exception 157 | * @desc 同步注册服务器信息 158 | */ 159 | public function syncRegister($serviceInfo) 160 | { 161 | $serviceName = $serviceInfo['name']; 162 | $serverList = ZConfig::get($serviceName, []); 163 | $key = $serviceInfo['ip'] . '_' . $serviceInfo['port'] . '_' . $serviceInfo['serverType']; 164 | $serverList[$key] = $serviceInfo; 165 | Scheduler::reload($serviceName, $serverList, 0); 166 | } 167 | } -------------------------------------------------------------------------------- /ant-lib/service/Base.php: -------------------------------------------------------------------------------- 1 | worker_pid . '_', true)); 27 | } 28 | 29 | 30 | /** 31 | * @param $serv \swoole_server 对像 32 | * @param $fd //文件描述符 33 | * @param $from_id //来自哪个reactor线程, 此参数基本用不上 34 | * @param $data //接收到的tcp数据 35 | * @return bool 36 | * @throws \Exception 37 | * @desc 收到tcp数据的业务处理 38 | */ 39 | public static function onReceive(\swoole_server $serv, $fd, $from_id, $data) 40 | { 41 | $startTime = microtime(true); 42 | common\Log::info([$data, substr($data, 4), $fd], 'proxy_tcp'); 43 | $realData = substr($data, 4); 44 | if ('ant-ping' === $realData) { //ping包,强制硬编码,不允许自定义 45 | return $serv->send($fd, pack('N', 8) . 'ant-pong'); //回pong包 46 | } 47 | if ('ant-reload' == $realData) { //重启包 48 | common\Log::info([], 'reload'); 49 | return $serv->reload(); 50 | } 51 | Request::addParams('_recv', 1); 52 | Request::parse($realData); 53 | if (Request::checkRequestTimeOut()) { 54 | //该请求已超时 55 | common\Log::info([Request::getParams()], 'request_timeout'); 56 | return false; 57 | } 58 | $params = Request::getParams(); 59 | $params['_fd'] = $fd; 60 | Request::setParams($params); 61 | 62 | if (!empty($params['_task'])) { 63 | //task任务, 回复task的任务id 64 | $taskId = self::getRequestId($serv); 65 | $params['taskId'] = $taskId; 66 | $params['requestId'] = Request::getRequestId(); 67 | $serv->task($params); 68 | $result = Response::display([ 69 | 'code' => 0, 70 | 'msg' => '', 71 | 'data' => [ 72 | 'taskId' => $taskId 73 | ] 74 | ]); 75 | $serv->send($fd, pack('N', strlen($result)) . $result); 76 | } else { 77 | if (empty($params['_recv'])) { 78 | //不用等处理结果,立即回复一个空包,表示数据已收到 79 | $result = Response::display([ 80 | 'code' => 0, 81 | 'msg' => '', 82 | 'data' => null 83 | ]); 84 | $serv->send($fd, pack('N', strlen($result)) . $result); 85 | } 86 | 87 | $result = ZRoute::route(); 88 | common\Log::info([$data, $fd, Request::getCtrl(), Request::getMethod(), $result], 'proxy_tcp'); 89 | if (!empty($params['_recv'])) { 90 | //发送处理结果 91 | $serv->send($fd, pack('N', strlen($result)) . $result); 92 | } 93 | } 94 | $executeTime = Response::getResponseTime() - $startTime; //获取程序执行时间 95 | common\Log::info(['tcp', Request::getCtrl() . DS . Request::getMethod(), $executeTime], 'monitor'); 96 | MClient::serviceDot(Request::getCtrl() . DS . Request::getMethod(), $executeTime); 97 | } 98 | 99 | 100 | /** 101 | * @param $request \swoole_http_request 102 | * @param $response \swoole_http_response 103 | * @throws \Exception 104 | * @desc http请求回调 105 | */ 106 | public static function onRequest($request, $response) 107 | { 108 | $startTime = microtime(true); 109 | if ($request->server['path_info'] == '/ant-ping') { 110 | common\Log::info([$request], 'http_ping'); 111 | $response->end('ant-pong'); 112 | return; 113 | } 114 | if ($request->server['path_info'] == '/favicon.ico') { 115 | common\Log::info([$request], 'favicon'); 116 | $response->end(); 117 | return; 118 | } 119 | 120 | common\Log::info([$request], 'proxy_http'); 121 | $param = []; 122 | $_GET = $_POST = $_REQUEST = $_COOKIE = $_FILES = null; 123 | if (!empty($request->get)) { 124 | $_GET = $request->get; 125 | $param = $request->get; 126 | } 127 | if (!empty($request->post)) { 128 | $_POST = $request->post; 129 | $param += $request->post; 130 | } 131 | 132 | if (!empty($request->cookie)) { 133 | $_COOKIE = $request->cookie; 134 | } 135 | 136 | if (!empty($request->files)) { 137 | $_FILES = $request->files; 138 | } 139 | 140 | foreach ($request->header as $key => $val) { 141 | $_SERVER['HTTP_' . strtoupper(str_replace('-', '_', $key))] = $val; 142 | } 143 | 144 | foreach ($request->server as $key => $val) { 145 | $_SERVER[strtoupper($key)] = $val; 146 | } 147 | 148 | $_REQUEST = $param; 149 | 150 | Request::addParams('_recv', 1); 151 | Request::parse($param); 152 | $params = Request::getParams(); 153 | if (!isset($params['_recv'])) { 154 | $params['_recv'] = 1; 155 | } 156 | $params['_fd'] = $request->fd; 157 | Request::setParams($params); 158 | 159 | if (Request::checkRequestTimeOut()) { 160 | //该请求已超时 161 | common\Log::info([Request::getParams()], 'request_timeout'); 162 | $response->status('499'); 163 | $response->end(); 164 | return; 165 | } 166 | 167 | if (!empty($params['_task'])) { 168 | //task任务, 回复task的任务id 169 | $serv = Request::getSocket(); 170 | $taskId = self::getRequestId($serv); 171 | $params['taskId'] = $taskId; 172 | $params['requestId'] = Request::getRequestId(); 173 | $serv->task($params); 174 | $result = Response::display([ 175 | 'code' => 0, 176 | 'msg' => '', 177 | 'data' => [ 178 | 'taskId' => $taskId 179 | ] 180 | ]); 181 | $response->end($result); 182 | } else { 183 | if (empty($params['_recv'])) { 184 | //不用等处理结果,立即回复一个空包,表示数据已收到 185 | $result = Response::display([ 186 | 'code' => 0, 187 | 'msg' => '', 188 | 'data' => null 189 | ]); 190 | $response->end($result); 191 | ZRoute::route(); 192 | } else { 193 | $result = ZRoute::route(); 194 | if (is_null($result)) { 195 | $response->end(''); 196 | } else { 197 | $response->end($result); 198 | } 199 | } 200 | } 201 | 202 | $executeTime = microtime(true) - $startTime; //获取程序执行时间 203 | common\Log::info(['http', $result, Request::getCtrl() . DS . Request::getMethod(), $executeTime], 'monitor'); 204 | MClient::serviceDot(Request::getCtrl() . DS . Request::getMethod(), $executeTime); 205 | } 206 | 207 | 208 | /** 209 | * @param \swoole_websocket_server $server 210 | * @param \swoole_http_request $request 211 | * @throws \Exception 212 | * @desc websocket握手成功后的回调 213 | */ 214 | public static function onOpen(\swoole_websocket_server $server, \swoole_http_request $request) 215 | { 216 | 217 | common\Log::info([$request], 'ws_open'); 218 | $callback = ZConfig::getField('socket', 'on_open_callback'); 219 | if (!$callback || !is_array($callback)) { 220 | return; 221 | } 222 | $param = []; 223 | $_GET = $_POST = $_REQUEST = $_COOKIE = $_FILES = null; 224 | if (!empty($request->get)) { 225 | $_GET = $request->get; 226 | $param = $request->get; 227 | } 228 | if (!empty($request->post)) { 229 | $_POST = $request->post; 230 | $param += $request->post; 231 | } 232 | 233 | if (!empty($request->cookie)) { 234 | $_COOKIE = $request->cookie; 235 | } 236 | 237 | if (!empty($request->files)) { 238 | $_FILES = $request->files; 239 | } 240 | 241 | foreach ($request->header as $key => $val) { 242 | $_SERVER['HTTP_' . strtoupper(str_replace('-', '_', $key))] = $val; 243 | } 244 | 245 | $param['_fd'] = $request->fd; 246 | $_REQUEST = $param; 247 | Request::setRequest($request); 248 | Request::addHeaders($request->header, true); 249 | Request::init($callback[0], $callback[1], $param); 250 | ZRoute::route(); 251 | Request::setRequest(null); 252 | } 253 | 254 | /** 255 | * @param \swoole_websocket_server $serv 256 | * @param \swoole_websocket_frame $frame 257 | * @return bool 258 | * @throws \Exception 259 | * @desc 收到一个websocket数据包回调 260 | */ 261 | public static function onMessage(\swoole_websocket_server $serv, \swoole_websocket_frame $frame) 262 | { 263 | $startTime = microtime(true); 264 | common\Log::info([$frame->data, $frame->fd], 'proxy_ws'); 265 | $fd = $frame->fd; 266 | $data = $frame->data; 267 | Request::addParams('_recv', 1); 268 | Request::parse($frame->data); 269 | if (Request::checkRequestTimeOut()) { 270 | //该请求已超时 271 | common\Log::info([Request::getParams()], 'request_timeout'); 272 | return false; 273 | } 274 | $params = Request::getParams(); 275 | $params['_fd'] = $frame->fd; 276 | Request::setParams($params); 277 | if (!empty($params['_task'])) { 278 | //task任务, 回复task的任务id 279 | $taskId = self::getRequestId($serv); 280 | $params['taskId'] = $taskId; 281 | $params['requestId'] = Request::getRequestId(); 282 | $serv->task($params); 283 | $result = Response::display([ 284 | 'code' => 0, 285 | 'msg' => '', 286 | 'data' => [ 287 | 'taskId' => $taskId 288 | ] 289 | ]); 290 | $serv->push($fd, $result); 291 | } else { 292 | if (empty($params['_recv'])) { 293 | //不用等处理结果,立即回复一个空包,表示数据已收到 294 | $result = Response::display([ 295 | 'code' => 0, 296 | 'msg' => '', 297 | 'data' => null 298 | ]); 299 | $serv->push($fd, $result); 300 | } 301 | 302 | $result = ZRoute::route(); 303 | common\Log::info([$data, $fd, Request::getCtrl(), Request::getMethod(), $result], 'proxy_tcp'); 304 | if (!empty($params['_recv'])) { 305 | //发送处理结果 306 | $serv->push($fd, $result); 307 | } 308 | } 309 | $executeTime = Response::getResponseTime() - $startTime; //获取程序执行时间 310 | common\Log::info(['ws', Request::getCtrl() . DS . Request::getMethod(), $executeTime], 'monitor'); 311 | MClient::serviceDot(Request::getCtrl() . DS . Request::getMethod(), $executeTime); 312 | } 313 | 314 | /** 315 | * @param $serv 316 | * @param $taskId 317 | * @param $fromId 318 | * @param $data 319 | * @return mixed 320 | * @throws \Exception 321 | * @desc task任务,适合处理一些耗时的业务 322 | */ 323 | public static function onTask($serv, $taskId, $fromId, $data) 324 | { 325 | $ret = Task::check($data); 326 | if ($ret) { //task特殊处理逻辑 327 | return Task::handle($ret); 328 | } 329 | $startTime = microtime(true); 330 | Request::setRequestId($data['requestId']); 331 | Request::parse($data); 332 | $result = ZRoute::route(); 333 | if (!empty($data['_recv'])) { //发送回执 334 | if (!empty($data['udp'])) { //udp请求 335 | $serv->sendto($data['clientInfo']['address'], $data['clientInfo']['port'], $result); 336 | } else { 337 | $serv->send($data['_fd'], pack('N', strlen($result)) . $result); 338 | } 339 | } 340 | $executeTime = microtime(true) - $startTime; 341 | common\Log::info(['task', $taskId, $fromId, Request::getCtrl() . DS . Request::getMethod(), $executeTime], 'monitor'); 342 | MClient::taskDot(Request::getCtrl() . DS . Request::getMethod(), $executeTime); 343 | } 344 | 345 | /** 346 | * @param $serv 347 | * @param $taskId 348 | * @param $data 349 | * @desc task处理完成之后,数据回调 350 | */ 351 | public static function onFinish($serv, $taskId, $data) 352 | { 353 | } 354 | 355 | 356 | /** 357 | * @param \swoole_server $serv 358 | * @param $data 359 | * @param $clientInfo 360 | * @throws \Exception 361 | * @desc 收到udp数据的处理 362 | */ 363 | public static function onPacket(\swoole_server $serv, $data, $clientInfo) 364 | { 365 | $startTime = microtime(true); 366 | common\Log::info([$data, $clientInfo], 'proxy_udp'); 367 | if ('ant-ping' == $data) { 368 | $serv->sendto($clientInfo['address'], $clientInfo['port'], 'ant-pong'); 369 | return; 370 | } 371 | 372 | if ('ant-reload' == $data) { 373 | common\Log::info([], 'reload'); 374 | $serv->reload(); 375 | return; 376 | } 377 | $params = Request::parse($data); 378 | $params['_fd'] = $clientInfo; 379 | Request::setFd($clientInfo); 380 | if (!empty($params['_task'])) { 381 | //task任务, 回复task的任务id 382 | $params['udp'] = 1; 383 | $params['clientInfo'] = $clientInfo; 384 | $taskId = self::getRequestId($serv); 385 | $params['taskId'] = $taskId; 386 | $params['requestId'] = Request::getRequestId(); 387 | $serv->task($params); 388 | if (!empty($params['_recv'])) { 389 | $result = Response::display([ 390 | 'code' => 0, 391 | 'msg' => '', 392 | 'data' => ['taskId' => $taskId] 393 | ]); 394 | $serv->sendto($clientInfo['address'], $clientInfo['port'], $result); 395 | } 396 | } else { 397 | $result = ZRoute::route(); 398 | if (!empty($params['_recv']) && $result) { 399 | $serv->sendto($clientInfo['address'], $clientInfo['port'], $result); 400 | } 401 | common\Log::info([$data, $clientInfo, $result], 'proxy_tcp'); 402 | } 403 | 404 | $executeTime = microtime(true) - $startTime; //获取程序执行时间 405 | common\Log::info(['udp', $executeTime], 'monitor'); 406 | MClient::serviceDot(Request::getCtrl() . DS . Request::getMethod(), $executeTime); 407 | } 408 | 409 | 410 | /** 411 | * @param $serv \swoole_server 412 | * @param $workerId 413 | * @throws \Exception 414 | * @desc worker/task进程启动后回调,可用于一些初始化业务和操作 415 | */ 416 | public static function onWorkerStart($serv, $workerId) 417 | { 418 | \register_shutdown_function(function () use ($serv) { 419 | $params = Request::getParams(); 420 | Request::setViewMode(ZConfig::getField('project', 'view_mode', 'Json')); 421 | common\Log::info([$params], 'shutdown'); 422 | $result = \call_user_func(ZConfig::getField('project', 'fatal_handler', 'ZPHP\ZPHP::fatalHandler')); 423 | if (!empty($params['_recv'])) { //发送回执 424 | common\Log::info([$params, $result], 'shutdown'); 425 | if (Request::isHttp()) { 426 | Response::getResponse()->end($result); 427 | } else { 428 | $serverType = ZConfig::get('socket', 'server_type'); 429 | switch ($serverType) { 430 | case Swoole::TYPE_WEBSOCKET: 431 | case Swoole::TYPE_WEBSOCKETS: 432 | $serv->push(Request::getFd(), $result); 433 | break; 434 | case Swoole::TYPE_UDP: 435 | $clientInfo = Request::getFd(); 436 | if (!empty($clientInfo['address'])) { 437 | $serv->sendto($clientInfo['address'], $clientInfo['port'], $result); 438 | } 439 | break; 440 | default: 441 | $serv->send(Request::getFd(), pack('N', strlen($result)) . $result); 442 | } 443 | } 444 | //@TODO 异常上报 445 | } 446 | }); 447 | common\Log::info([$workerId], 'info'); 448 | $timer = ZConfig::get('timer', []); 449 | if (!empty($timer) && 0 === intval($workerId)) { 450 | common\Log::info(['timer', $workerId], 'info'); 451 | foreach ($timer as $index => $item) { 452 | if (!empty($item['ms']) && 453 | !empty($item['callback']) && 454 | \is_callable($item['callback']) 455 | ) { 456 | common\Log::info([$item, $workerId], 'info'); 457 | \swoole_timer_tick($item['ms'], $item['callback'], isset($item['params']) ? $item['params'] : null); 458 | } 459 | } 460 | } 461 | 462 | $reloadPath = ZConfig::getField('project', 'reload_path', []); 463 | $reloadPath += [ 464 | ZPHP::getConfigPath() . DS . '..' . DS . 'public' 465 | ]; 466 | if (is_array($reloadPath)) { 467 | foreach ($reloadPath as $path) { 468 | ZConfig::mergePath($path); 469 | } 470 | } 471 | $workNum = ZConfig::getField('socket', 'worker_num'); 472 | if ($workerId == ($workNum - 1)) { 473 | ZCache::getInstance('Task')->load(); 474 | ZConn::getInstance('Task')->load(); 475 | } 476 | } 477 | 478 | /** 479 | * @param $serv 480 | * @param $workerId 481 | * @param $workerPid 482 | * @param $exitCode 483 | * @desc 工作进程异常之后 484 | */ 485 | public static function onWorkerError($serv, $workerId, $workerPid, $exitCode) 486 | { 487 | } 488 | 489 | 490 | /** 491 | * @param $serv \swoole_server 492 | * @param $fd 493 | * @param $from_id 494 | * @throws \Exception 495 | * @desc 建立连接回调 496 | */ 497 | public static function onConnect($serv, $fd, $from_id) 498 | { 499 | common\Log::info([$fd], 'on_connect'); 500 | $callback = ZConfig::getField('socket', 'on_connect_callback'); 501 | if (!$callback || !is_array($callback)) { 502 | return; 503 | } 504 | 505 | Request::init($callback[0], $callback[1], [ 506 | '_fd' => $fd 507 | ]); 508 | ZRoute::route(); 509 | } 510 | 511 | /** 512 | * @param $serv 513 | * @param $fd 514 | * @param $from_id 515 | * @throws \Exception 516 | * @desc 连接关闭回调 517 | */ 518 | public static function onClose($serv, $fd, $from_id) 519 | { 520 | common\Log::info([$fd], 'on_close'); 521 | $callback = ZConfig::getField('socket', 'on_close_callback'); 522 | if (!$callback || !is_array($callback)) { 523 | return; 524 | } 525 | Request::init($callback[0], $callback[1], [ 526 | '_fd' => $fd 527 | ]); 528 | ZRoute::route(); 529 | } 530 | 531 | /** 532 | * @param $serv 533 | * @param $workerId 534 | * @throws \Exception 535 | * @desc worker进程退出时回调 536 | */ 537 | public static function onWorkerStop($serv, $workerId) 538 | { 539 | $workNum = ZConfig::getField('socket', 'worker_num'); 540 | if ($workerId == ($workNum - 1)) { 541 | ZCache::getInstance('Task')->flush(); 542 | ZConn::getInstance('Task')->flush(); 543 | } 544 | } 545 | } 546 | -------------------------------------------------------------------------------- /ant-lib/socket/Handler/Soa.php: -------------------------------------------------------------------------------- 1 | register( 39 | ZConfig::get('project_name'), 40 | $ip, 41 | $port, 42 | ZConfig::getField('soa', 'serverType', ZConfig::getField('socket', 'server_type')) 43 | ); 44 | } catch (\Exception $e) { 45 | $server->shutdown(); 46 | $result = \call_user_func(ZConfig::getField('project', 'exception_handler', 'ZPHP\ZPHP::exceptionHandler'), $e); 47 | Log::info([ZConfig::get('project_name'), $ip, $port, $result], 'register_error'); 48 | return $result; 49 | } 50 | } 51 | 52 | $soaConfig = ZConfig::get('soa'); 53 | if (!empty($soaConfig)) { 54 | //服务注册 55 | if (isset($soaConfig['serviceIp'])) { 56 | $serverIp = $soaConfig['serviceIp']; 57 | } else { 58 | $serverIp = ZConfig::getField('socket', 'host'); 59 | if ('0.0.0.0' == $serverIp) { 60 | $serverIp = Utils::getLocalIp(); 61 | } 62 | } 63 | $rpcClient = new TcpClient( 64 | ZConfig::getField('soa', 'ip', null, true), 65 | ZConfig::getField('soa', 'port', null, true), 66 | ZConfig::getField('soa', 'timeOut', 3000) 67 | ); 68 | $serverName = ZConfig::getField('soa', 'serviceName', ZConfig::get('project_name')); 69 | $serverPort = ZConfig::getField('soa', 'servicePort', ZConfig::getField('socket', 'port')); 70 | $data = $rpcClient->setApi('main')->call('register', [ 71 | 'serviceName' => $serverName, 72 | 'serviceIp' => $serverIp, 73 | 'servicePort' => $serverPort, 74 | 'serverType' => ZConfig::getField('soa', 'serverType', ZConfig::getField('socket', 'server_type')), 75 | ]); 76 | 77 | if (empty($data)) { //注册失败,服务停止 78 | $server->shutdown(); 79 | Log::info([$serverName, $serverIp, $serverPort], 'register_error'); 80 | return $serverName . ':' . $serverIp . ':' . $serverPort . 'register_error'; 81 | } else { 82 | try { 83 | $data->getBody(); 84 | //配置同步 85 | LoadClass::getService('AntConfigAgent')->syncAll($serverName); 86 | } catch (\Exception $e) { 87 | $server->shutdown(); 88 | $result = \call_user_func(ZConfig::getField('project', 'exception_handler', 'ZPHP\ZPHP::exceptionHandler'), $e); 89 | Log::info([$serverName, $serverIp, $serverPort, $result], 'register_error'); 90 | return $result; 91 | } 92 | } 93 | } 94 | } 95 | 96 | 97 | /** 98 | * @param $server 99 | * @return mixed|void 100 | * @throws \Exception 101 | * @desc 服务下线回调 102 | */ 103 | public static function drop($server) 104 | { 105 | //是否自下线 106 | $isRegisterProject = ZConfig::getField('project', 'is_register_project', 0); 107 | if ($isRegisterProject) { 108 | $host = ZConfig::getField('socket', 'host'); 109 | if ('0.0.0.0' == $host) { 110 | $host = Utils::getLocalIp(); 111 | } 112 | $port = ZConfig::getField('socket', 'port'); 113 | $serverName = ZConfig::getField('soa', 'serviceName', ZConfig::get('project_name')); 114 | try { 115 | LoadClass::getService('ServiceList')->drop( 116 | $host, 117 | $port 118 | ); 119 | return; 120 | } catch (\Exception $e) { 121 | $result = \call_user_func(ZConfig::getField('project', 'exception_handler', 'ZPHP\ZPHP::exceptionHandler'), $e); 122 | Log::info([$serverName, $host, $port, $result], 'drop_error'); 123 | return $result; 124 | } 125 | } 126 | 127 | $soaConfig = ZConfig::get('soa'); 128 | if (!empty($soaConfig)) { 129 | //服务下线 130 | if (isset($soaConfig['serviceIp'])) { 131 | $serverIp = $soaConfig['serviceIp']; 132 | } else { 133 | $serverIp = ZConfig::getField('socket', 'host'); 134 | if ('0.0.0.0' == $serverIp) { 135 | $serverIp = Utils::getLocalIp(); 136 | } 137 | } 138 | $rpcClient = new TcpClient( 139 | ZConfig::getField('soa', 'ip', null, true), 140 | ZConfig::getField('soa', 'port', null, true), 141 | ZConfig::getField('soa', 'timeOut', 3000) 142 | ); 143 | $serverName = ZConfig::getField('soa', 'serviceName', ZConfig::get('project_name')); 144 | $rpcClient->setApi('main')->call('drop', [ 145 | 'serviceName' => $serverName, 146 | 'serviceIp' => $serverIp, 147 | 'servicePort' => ZConfig::getField('soa', 'servicePort', ZConfig::getField('socket', 'port')), 148 | ]); 149 | } 150 | } 151 | 152 | } -------------------------------------------------------------------------------- /ant-lib/socket/Http.php: -------------------------------------------------------------------------------- 1 | worker_num是表示是task进程 59 | * @desc worker/task进程启动后回调,可用于一些初始化业务和操作 60 | */ 61 | public function onWorkerStart($serv, $workerId) 62 | { 63 | opcache_reset(); 64 | parent::onWorkerStart($serv, $workerId); 65 | Handler\Proxy::onWorkerStart($serv, $workerId); 66 | } 67 | 68 | /** 69 | * @param $serv //swoole_server对像 70 | * @param $workerId //worker/task id 71 | * @param $workerPid //worker/task系统进程id 72 | * @param $exitCode //退出错误码 73 | * @desc 工作进程异常退出之后回调 74 | */ 75 | public function onWorkerError($serv, $workerId, $workerPid, $exitCode) 76 | { 77 | Handler\Proxy::onWorkerError($serv, $workerId, $workerPid, $exitCode); 78 | } 79 | 80 | public function onWorkerStop($server, $workerId) 81 | { 82 | Handler\Proxy::onWorkerStop($server, $workerId); 83 | } 84 | 85 | public function onClose() 86 | { 87 | list($serv, $fd, $from_id) = func_get_args(); 88 | Handler\Proxy::onClose($serv, $fd, $from_id); 89 | } 90 | 91 | public function onConnect() 92 | { 93 | list($serv, $fd, $from_id) = func_get_args(); 94 | Handler\Proxy::onConnect($serv, $fd, $from_id); 95 | } 96 | } 97 | 98 | -------------------------------------------------------------------------------- /ant-lib/socket/Udp.php: -------------------------------------------------------------------------------- 1 | getString('serviceName', 'undefined'); 22 | $serverIp = $this->getString('serviceIp', 'undefined'); 23 | $serverPort = $this->getString('servicePort', 'undefined'); 24 | $api = $this->getString('api', 'undefined'); 25 | $time = $this->getFloat('time', 0); 26 | common\Log::info([ 27 | $serverName, $serverIp, $serverPort, $api, $time 28 | ], 'client'); 29 | } 30 | 31 | /** 32 | * @desc 服务提供者时间打点 33 | */ 34 | public function service() 35 | { 36 | $serverName = $this->getString('serviceName', 'undefined'); 37 | $serverIp = $this->getString('serviceIp', 'undefined'); 38 | $serverPort = $this->getString('servicePort', 'undefined'); 39 | $api = $this->getString('api', 'undefined'); 40 | $time = $this->getFloat('time', 0); 41 | common\Log::info([ 42 | $serverName, $serverIp, $serverPort, $api, $time 43 | ], 'service'); 44 | } 45 | } -------------------------------------------------------------------------------- /ant-monitor/config/default/config.php: -------------------------------------------------------------------------------- 1 | 'Ant', 10 | 'project_name' => 'ant-monitor-center', 11 | 'project' => array( 12 | 'debug_mode' => 1, //打开调试模式 13 | ), 14 | 'socket' => array( 15 | 'host' => '0.0.0.0', //socket 监听ip 16 | 'port' => 8891, //socket 监听端口 17 | 'server_type' => Swoole::TYPE_UDP, //socket 业务模型 tcp/udp/http/websocket 18 | 'daemonize' => 1, //是否开启守护进程 19 | 'client_class' => 'socket\\Udp', //socket 回调类 20 | 'protocol' => 'Ant', //socket通信数据协议 21 | 'work_mode' => 3, //工作模式:1:单进程单线程 2:多线程 3: 多进程 22 | 'worker_num' => 32, //工作进程数 23 | 'task_worker_num' => 32, //工作进程数 24 | 'max_request' => 0, //单个进程最大处理请求数 25 | ) 26 | ); 27 | -------------------------------------------------------------------------------- /ant-monitor/config/default/register.php: -------------------------------------------------------------------------------- 1 | array( 4 | 'ip' => '10.94.107.22', 5 | 'port' => 9949, 6 | ), 7 | ); -------------------------------------------------------------------------------- /ant-monitor/config/public/README: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shenzhe/ant/88b00f4017d3a055402074c2786977bf20839c6f/ant-monitor/config/public/README -------------------------------------------------------------------------------- /ant-monitor/webroot/main.php: -------------------------------------------------------------------------------- 1 | 'Ant', 9 | 'project_name' => 'ant-config-center', 10 | 'project' => [ 11 | 'debug_mode' => 0, //打开调试模式 12 | ], 13 | 'socket' => array( 14 | 'host' => '0.0.0.0', //socket 监听ip 15 | 'port' => 8500, //socket 监听端口 16 | 'server_type' => Swoole::TYPE_TCP, //socket 业务模型 tcp/udp/http/websocket 17 | 'daemonize' => 1, //是否开启守护进程 18 | 'work_mode' => 3, //工作模式:1:单进程单线程 2:多线程 3: 多进程 19 | 'worker_num' => 32, //工作进程数 20 | 'task_worker_num' => 32, //工作进程数 21 | 'max_request' => 0, //单个进程最大处理请求数 22 | 'addlisten' => array( //开启udp监听 23 | 'ip' => '0.0.0.0', 24 | 'port' => 8501 25 | ), 26 | ), 27 | ); 28 | -------------------------------------------------------------------------------- /ant-proxy/config/mysql/pdo.php: -------------------------------------------------------------------------------- 1 | array( 4 | 'common' => array( 5 | 'dsn' => 'mysql:host=127.0.0.1;port=3306', //dsn地址 6 | 'name' => 'common', //自定义名称 7 | 'user' => 'root', // db用户名 8 | 'pass' => '123456', //db密码 9 | 'dbname' => 'user_center', //db默认数据库 10 | 'charset' => 'UTF8', //db默认编码 11 | 'pconnect' => false, //是否开启持久连接,swoole模式必需关闭 12 | 'ping' => 1, //是否开始ping检测 13 | 'pingtime' => 7200, //ping检测时间 14 | ), 15 | ), 16 | ]; -------------------------------------------------------------------------------- /ant-proxy/config/mysql/register.php: -------------------------------------------------------------------------------- 1 | array( 10 | 'ip' => '10.94.107.22', 11 | 'port' => 9949 12 | ), 13 | ); -------------------------------------------------------------------------------- /ant-proxy/webroot/main.php: -------------------------------------------------------------------------------- 1 | fetchAll(['registerKey=' => "'$key'"]); 36 | if (!empty($allService)) { 37 | foreach ($allService as $item) { 38 | try { 39 | if ($item->ip . ':' . $item->port == $key) { 40 | continue; 41 | } 42 | $rpc = null; 43 | switch ($item->serverType) { 44 | case Swoole::TYPE_TCP: 45 | $rpc = new TcpClient($item->ip, $item->port); 46 | break; 47 | case Swoole::TYPE_UDP: 48 | $rpc = new UdpClient($item->ip, $item->port); 49 | break; 50 | case Swoole::TYPE_HTTP: 51 | case Swoole::TYPE_HTTPS: 52 | case Swoole::TYPE_WEBSOCKET: 53 | case Swoole::TYPE_WEBSOCKETS: 54 | $rpc = new HttpClient($item->ip, $item->port); 55 | break; 56 | } 57 | if (!$rpc) { 58 | continue; 59 | } 60 | $result = $rpc->ping(); //发送ping包 61 | if (false === $result) { //超时 62 | Log::info(['false', $rpc->isConnected(), $item->name, $item->ip, $item->port, $item->status], 'ping'); 63 | if (1 == $item->status) { //在线状态设置为离线状态 64 | $service->update(['status' => 0], ['id=' => $item->id]); 65 | LoadClass::getService('Subscriber')->sync($item); 66 | } 67 | continue; 68 | } 69 | Log::info(['success', $rpc->isConnected(), $item->name, $item->ip, $item->port, $item->status, $result], 'ping'); 70 | if ('ant-pong' == $result) { 71 | if (0 == $item->status) { //离线状态设置为在线状态 72 | //@TODO 可以不单条更新,改为批量更新 73 | $service->update(['status' => 1], ['id=' => $item->id]); 74 | LoadClass::getService('Subscriber')->sync($item); 75 | } 76 | continue; 77 | } 78 | } catch (\Exception $e) { 79 | //心跳回复失败,设置离线状态 80 | Log::info(['fail', $e->getMessage(), $e->getCode(), isset($rpc) ? $rpc->isConnected() : '', $item->name, $item->ip, $item->port, $item->status], 'ping'); 81 | if (1 == $item->status) { 82 | //@TODO 可以不单条更新,改为批量更新 83 | $service->update(['status' => 0], ['id=' => $item->id]); 84 | LoadClass::getService('Subscriber')->sync($item); 85 | } 86 | } 87 | } 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /ant-register/apps/ctrl/main.php: -------------------------------------------------------------------------------- 1 | getString('serviceName'); 26 | $serviceIp = $this->getString('serviceIp'); 27 | $servicePort = $this->getInteger('servicePort'); 28 | $serverType = $this->getString('serverType'); 29 | /** 30 | * @var $service \service\ServiceList 31 | */ 32 | $service = LoadClass::getService('ServiceList'); 33 | return $this->getView([ 34 | 'serviceInfo' => $service->register($serviceName, $serviceIp, $servicePort, $serverType) 35 | ]); 36 | } 37 | 38 | public function drop() 39 | { 40 | // $serviceName = $this->getString('serviceName'); 41 | $serviceIp = $this->getString('serviceIp'); 42 | $servicePort = $this->getInteger('servicePort'); 43 | /** 44 | * @var $service \service\ServiceList 45 | */ 46 | $service = LoadClass::getService('ServiceList'); 47 | return $this->getView([ 48 | 'serviceInfo' => $service->drop($serviceIp, $servicePort) 49 | ]); 50 | } 51 | 52 | /** 53 | * @return array 54 | * @desc 获取某服务名所有的ip:port 55 | */ 56 | public function getList() 57 | { 58 | $serviceName = $this->getString('serviceName'); 59 | $subscriber = $this->getString('subscriber', ''); 60 | if (!empty($subscriber) && $subscriber != $serviceName) { //添加订阅者 61 | LoadClass::getService('Subscriber')->subscriber($serviceName, $subscriber); 62 | } 63 | /** 64 | * @var $service \service\ServiceList 65 | */ 66 | $service = LoadClass::getService('ServiceList'); 67 | return $this->getView([ 68 | 'serviceList' => $service->getServiceList($serviceName) 69 | ]); 70 | } 71 | } -------------------------------------------------------------------------------- /ant-register/apps/dao/ServiceList.php: -------------------------------------------------------------------------------- 1 | $this->ip, 34 | 'port' => $this->port, 35 | 'status' => $this->status, 36 | 'rate' => $this->rate, 37 | 'serverType'=>$this->serverType 38 | ]; 39 | } 40 | } -------------------------------------------------------------------------------- /ant-register/apps/entity/Subscriber.php: -------------------------------------------------------------------------------- 1 | fetchOne([ 35 | 'ip = ' => "'{$serviceIp}'", 36 | 'port = ' => $servicePort 37 | ]); 38 | $host = ZConfig::getField('socket', 'host'); 39 | if ('0.0.0.0' == $host) { 40 | $host = Utils::getLocalIp(); 41 | } 42 | $key = $host . ":" . ZConfig::getField('socket', 'port'); 43 | if (empty($serviceInfo)) { 44 | $serviceInfo = new entity\ServiceList(); 45 | $serviceInfo->name = $serviceName; 46 | $serviceInfo->ip = $serviceIp; 47 | $serviceInfo->port = $servicePort; 48 | $serviceInfo->status = 1; 49 | $serviceInfo->registerTime = time(); 50 | $serviceInfo->startTime = time(); 51 | $serviceInfo->dropTime = 0; 52 | $serviceInfo->registerKey = $key; 53 | $serviceInfo->serverType = $serverType; 54 | $id = LoadClass::getDao('ServiceList')->add($serviceInfo); 55 | $serviceInfo->id = $id; 56 | } else if (empty($serviceInfo->status)) { 57 | if ($serviceInfo->name !== $serviceName) { 58 | throw new RegisterException(ERROR::SERVICE_NAME_ERROR); 59 | } 60 | if ($serviceInfo->registerKey == $key) { 61 | $ret = LoadClass::getDao('ServiceList')->update([ 62 | 'status' => 1, 63 | 'startTime' => time(), 64 | 'serverType' => $serverType 65 | ], ['id=' => $serviceInfo->id]); 66 | } else { 67 | $ret = LoadClass::getDao('ServiceList')->update([ 68 | 'status' => 1, 69 | 'startTime' => time(), 70 | 'registerKey' => $key, 71 | 'serverType' => $serverType 72 | ], ['id=' => $serviceInfo->id]); 73 | } 74 | if ($ret) { 75 | $serviceInfo->status = 1; 76 | } 77 | } 78 | LoadClass::getService('Subscriber')->sync($serviceInfo); 79 | return $serviceInfo; 80 | } 81 | 82 | /** 83 | * @param $serviceIp 84 | * @param $servicePort 85 | * @return mixed 86 | * @desc 服务摘除 87 | */ 88 | public function drop($serviceIp, $servicePort) 89 | { 90 | $serviceInfo = LoadClass::getDao('ServiceList')->fetchOne([ 91 | 'ip = ' => "'{$serviceIp}'", 92 | 'port = ' => $servicePort 93 | ]); 94 | 95 | if (!empty($serviceInfo->status)) { 96 | if (LoadClass::getDao('ServiceList')->update(['status' => 0, 'dropTime' => time()], ['id=' => $serviceInfo->id])) { 97 | $serviceInfo->status = 0; 98 | } 99 | LoadClass::getService('Subscriber')->sync($serviceInfo); 100 | } 101 | return $serviceInfo; 102 | } 103 | 104 | /** 105 | * @param $serviceName 106 | * @return int 107 | * @desc 移除某服务所有机器 108 | */ 109 | public function dropAll($serviceName) 110 | { 111 | return LoadClass::getDao('ServiceList')->update(['status' => 0, 'dropTime' => time()], ['name=' => $serviceName]); 112 | } 113 | 114 | /** 115 | * @param $serviceName 116 | * @return mixed 117 | * @desc 获取服务列表 118 | */ 119 | public function getServiceList($serviceName) 120 | { 121 | $serviceList = LoadClass::getDao('ServiceList')->fetchAll([ 122 | 'name=' => "'{$serviceName}'" 123 | ]); 124 | return $serviceList; 125 | } 126 | 127 | } -------------------------------------------------------------------------------- /ant-register/apps/service/Subscriber.php: -------------------------------------------------------------------------------- 1 | fetchOne([ 28 | 'serviceName=' => "'{$serviceName}'", 29 | 'subscriber=' => "'{$subscriber}'" 30 | ]); 31 | if (empty($record)) { 32 | return LoadClass::getDao('Subscriber')->add([ 33 | 'serviceName' => $serviceName, 34 | 'subscriber' => $subscriber, 35 | ]); 36 | } 37 | return $record->id; 38 | } 39 | 40 | /** 41 | * @param $serviceInfo \entity\ServiceList 42 | * @return bool 43 | */ 44 | public function sync($serviceInfo) 45 | { 46 | $subscriberList = LoadClass::getDao('Subscriber')->fetchAll([ 47 | 'serviceName=' => "'{$serviceInfo->name}'", 48 | ]); 49 | if (empty($subscriberList)) { 50 | return false; 51 | } 52 | 53 | foreach ($subscriberList as $subscriber) { 54 | /** 55 | * @var $subscriber \entity\Subscriber 56 | */ 57 | $serviceList = LoadClass::getDao('ServiceList')->fetchAll([ 58 | 'name=' => "'{$subscriber->subscriber}'", 59 | ]); 60 | if (empty($serviceList)) { 61 | continue; 62 | } 63 | foreach ($serviceList as $sub) { 64 | /** 65 | * @var $sub \entity\ServiceList 66 | */ 67 | if (!$sub->status) { 68 | continue; //没有运行 69 | } 70 | try { 71 | if ($sub->serverType == Swoole::TYPE_TCP) { 72 | $service = new TcpClient($sub->ip, $sub->port); 73 | } elseif ($sub->serverType == Swoole::TYPE_UDP) { 74 | $service = new UdpClient($sub->ip, $sub->port); 75 | } elseif ($sub->serverType == Swoole::TYPE_HTTP) { 76 | continue; 77 | } 78 | 79 | switch ($sub->serverType) { 80 | case Swoole::TYPE_TCP: 81 | $service = new TcpClient($sub->ip, $sub->port); 82 | break; 83 | case Swoole::TYPE_UDP: 84 | $service = new UdpClient($sub->ip, $sub->port); 85 | break; 86 | case Swoole::TYPE_HTTP: 87 | case Swoole::TYPE_HTTPS: 88 | case Swoole::TYPE_WEBSOCKET: 89 | case Swoole::TYPE_WEBSOCKETS: 90 | $service = new HttpClient($sub->ip, $sub->port); 91 | break; 92 | } 93 | $service->setApi('antConfigAgent')->call('syncRegister', [ 94 | 'serviceInfo' => $serviceInfo 95 | ]); 96 | } catch (\Exception $e) { 97 | //发送错误 98 | Log::info([$e->getMessage(), $e->getCode()], 'syncRegister_error'); 99 | } 100 | } 101 | } 102 | } 103 | 104 | } -------------------------------------------------------------------------------- /ant-register/config/public/README: -------------------------------------------------------------------------------- 1 | 缓存配置 -------------------------------------------------------------------------------- /ant-register/config/register/config.php: -------------------------------------------------------------------------------- 1 | 'Ant', 6 | 'project_name' => 'ant-register-center', 7 | 'project' => [ 8 | 'is_register_project' => 1, //是否为注册服务器 9 | 'debug_mode' => 1, //是否打开调试模式 10 | ], 11 | 'socket' => array( 12 | 'host' => '0.0.0.0', //socket 监听ip 13 | 'port' => 9949, //socket 监听端口 14 | 'server_type' => Swoole::TYPE_TCP, //socket 业务模型 tcp/udp/http/websocket 15 | 'daemonize' => 1, //是否开启守护进程 16 | 'worker_num' => 32, //工作进程数 17 | 'task_worker_num' => 32, //工作进程数 18 | 'max_request' => 0, //单个进程最大处理请求数 19 | 'addlisten' => array( //开启udp监听 20 | 'ip' => '0.0.0.0', 21 | 'port' => 10060 22 | ) 23 | ), 24 | 'timer' => array( //定时器 25 | array( 26 | 'ms' => 5000, //间隔毫秒 27 | 'callback' => 'common\Timer::checkPing' //回调函数 28 | ), 29 | ), 30 | ); 31 | -------------------------------------------------------------------------------- /ant-register/config/register/pdo.php: -------------------------------------------------------------------------------- 1 | array( 4 | 'common' => array( 5 | 'dsn' => 'mysql:host=127.0.0.1;port=3306', //dsn地址 6 | 'name' => 'common', //自定义名称 7 | 'user' => 'root', // db用户名 8 | 'pass' => '123456', //db密码 9 | 'dbname' => 'register_center', //db默认数据库 10 | 'charset' => 'UTF8', //db默认编码 11 | 'pconnect' => false, //是否开启持久连接,swoole模式必需关闭 12 | 'ping' => 1, //是否开始ping检测 13 | 'pingtime' => 7200, //ping检测时间 14 | ), 15 | ), 16 | ]; -------------------------------------------------------------------------------- /ant-register/config/register/register.php: -------------------------------------------------------------------------------- 1 | array( 11 | ), 12 | ); -------------------------------------------------------------------------------- /ant-register/sql/register_center.sql: -------------------------------------------------------------------------------- 1 | -- phpMyAdmin SQL Dump 2 | -- version 4.4.15.8 3 | -- https://www.phpmyadmin.net 4 | -- 5 | -- Host: localhost 6 | -- Generation Time: 2017-01-11 21:05:02 7 | -- 服务器版本: 5.6.33-log 8 | -- PHP Version: 7.0.14 9 | 10 | SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; 11 | SET time_zone = "+00:00"; 12 | 13 | 14 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 15 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 16 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 17 | /*!40101 SET NAMES utf8mb4 */; 18 | 19 | -- 20 | -- Database: `register_center` 21 | -- 22 | CREATE DATABASE IF NOT EXISTS `register_center` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; 23 | USE `register_center`; 24 | 25 | -- -------------------------------------------------------- 26 | 27 | -- 28 | -- 表的结构 `service_list` 29 | -- 30 | 31 | DROP TABLE IF EXISTS `service_list`; 32 | CREATE TABLE IF NOT EXISTS `service_list` ( 33 | `id` int(11) NOT NULL, 34 | `name` char(50) NOT NULL COMMENT '服务名称', 35 | `ip` char(15) NOT NULL COMMENT '服务ip', 36 | `port` mediumint(8) NOT NULL COMMENT '服务端口', 37 | `status` tinyint(1) NOT NULL COMMENT '运行状态', 38 | `rate` smallint(4) NOT NULL COMMENT '权重', 39 | `registerTime` int(10) NOT NULL COMMENT '注册时间', 40 | `startTime` int(10) NOT NULL COMMENT '启动时间', 41 | `dropTime` int(10) NOT NULL COMMENT '停止时间', 42 | `registerKey` varchar(100) NOT NULL COMMENT '从哪个注册服务器注册的', 43 | `serverType` smallint(4) NOT NULL DEFAULT '0' COMMENT '服务类型' 44 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='服务表'; 45 | 46 | -- -------------------------------------------------------- 47 | 48 | -- 49 | -- 表的结构 `subscriber` 50 | -- 51 | 52 | DROP TABLE IF EXISTS `subscriber`; 53 | CREATE TABLE IF NOT EXISTS `subscriber` ( 54 | `id` int(11) NOT NULL, 55 | `serviceName` varchar(100) NOT NULL COMMENT '服务名', 56 | `subcriber` varchar(100) NOT NULL COMMENT '订阅者' 57 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 58 | 59 | -- 60 | -- Indexes for dumped tables 61 | -- 62 | 63 | -- 64 | -- Indexes for table `service_list` 65 | -- 66 | ALTER TABLE `service_list` 67 | ADD PRIMARY KEY (`id`), 68 | ADD UNIQUE KEY `idx_ip_port` (`ip`,`port`) USING BTREE, 69 | ADD KEY `idx_name` (`name`) USING BTREE, 70 | ADD KEY `registerKey` (`registerKey`); 71 | 72 | -- 73 | -- Indexes for table `subscriber` 74 | -- 75 | ALTER TABLE `subscriber` 76 | ADD PRIMARY KEY (`id`), 77 | ADD KEY `serviceName` (`serviceName`), 78 | ADD KEY `subcriber` (`subcriber`); 79 | 80 | -- 81 | -- AUTO_INCREMENT for dumped tables 82 | -- 83 | 84 | -- 85 | -- AUTO_INCREMENT for table `service_list` 86 | -- 87 | ALTER TABLE `service_list` 88 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; 89 | -- 90 | -- AUTO_INCREMENT for table `subscriber` 91 | -- 92 | ALTER TABLE `subscriber` 93 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; 94 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 95 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 96 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 97 | -------------------------------------------------------------------------------- /ant-register/webroot/main.php: -------------------------------------------------------------------------------- 1 | header = $header; 22 | $this->body = $body; 23 | } 24 | 25 | public function getHeader() 26 | { 27 | return $this->header; 28 | } 29 | 30 | /** 31 | * @return null|array 32 | * @throws PackerException 33 | */ 34 | public function getBody() 35 | { 36 | if (!empty($this->body['code'])) { 37 | throw new PackerException($this->body['code'] . ':' . $this->body['msg']); 38 | } 39 | return $this->body; 40 | } 41 | 42 | public function getCode() 43 | { 44 | return $this->body['code']; 45 | } 46 | 47 | public function getMsg() 48 | { 49 | return $this->body['msg']; 50 | } 51 | 52 | public function getData() 53 | { 54 | return $this->body['data']; 55 | } 56 | } -------------------------------------------------------------------------------- /ant-rpc/scheduler/Adapter/Vote.php: -------------------------------------------------------------------------------- 1 | getOne($serviceName, $serverList); 71 | } 72 | 73 | /** 74 | * @param $serviceName 75 | * @param $soaConfig 76 | * @return mixed|null|array 77 | * @throws SchedulerException 78 | * @throws \Exception 79 | */ 80 | public static function getList($serviceName, $soaConfig) 81 | { 82 | if (ZConfig::get('project_name') === Consts::REGISTER_SERVER_NAME) { 83 | $serverList = LoadClass::getService('ServiceList')->getServiceList($serviceName); 84 | if (!empty($serverList)) { 85 | $serverList = json_decode(json_encode($serverList), true); 86 | } 87 | return $serverList; 88 | } 89 | $serverList = ZConfig::get($serviceName); 90 | if (empty($serverList)) { 91 | $serverList = self::getListForRpc($serviceName, $soaConfig); 92 | } 93 | 94 | if (empty($serverList)) { 95 | throw new SchedulerException($serviceName . " serverlist empty", -1); 96 | } 97 | return $serverList; 98 | } 99 | 100 | /** 101 | * @param $serviceName 102 | * @param null $soaConfig 103 | * @return array 104 | * @throws SchedulerException 105 | * @throws \Exception 106 | */ 107 | public static function getListForRpc($serviceName, $soaConfig = null) 108 | { 109 | if (!$soaConfig) { 110 | $soaConfig = ZConfig::get('soa'); 111 | if (empty($soaConfig)) { 112 | throw new SchedulerException('soa config empty'); 113 | } 114 | } 115 | $rpcClient = new TcpClient($soaConfig['ip'], $soaConfig['port'], empty($soaConfig['timeOut']) ? 0 : $soaConfig['timeOut']); 116 | $isDot = Consts::MONITOR_SERVER_NAME == $serviceName ? 0 : 1; 117 | $data = $rpcClient->setApi('main')->setDot($isDot)->call('getList', [ 118 | 'serviceName' => $serviceName, 119 | 'subscriber' => ZConfig::getField('soa', 'serviceName', ZConfig::get('project_name')), 120 | ]); 121 | if ($data) { 122 | $data = $data->getData(); 123 | if (!empty($data['serviceList'])) { 124 | $serverList = $data['serviceList']; 125 | self::reload($serviceName, $serverList); 126 | return $serverList; 127 | } 128 | } 129 | } 130 | 131 | /** 132 | * @param $serviceName 133 | * @param $serverList 134 | * @param int $rebuild 135 | * @return bool 136 | */ 137 | public static function reload($serviceName, $serverList, $rebuild = 1) 138 | { 139 | $path = ZPHP::getConfigPath() . DS . '..' . DS . 'public'; 140 | if (!is_dir($path)) { 141 | if (!mkdir($path)) { 142 | return false; 143 | } 144 | } 145 | if ($rebuild) { 146 | foreach ($serverList as $index => $server) { 147 | $serverList[$server['ip'] . '_' . $server['port'] . '_' . $server['serverType']] = $server; 148 | unset($serverList[$index]); 149 | } 150 | } 151 | $filename = $path . DS . 'service_' . $serviceName . '.php'; 152 | file_put_contents($filename, "" . var_export($serverList, true) . " 154 | );"); 155 | ZConfig::mergeFile($filename); 156 | } 157 | 158 | /** 159 | * @param $serviceName 160 | * @param $ip 161 | * @param $port 162 | * @param $type 163 | * @throws SchedulerException 164 | * @throws \Exception 165 | * @desc 服务选择成功,回调处理 166 | */ 167 | public static function success($serviceName, $ip, $port, $type) 168 | { 169 | $soaConfig = ZConfig::get('soa'); 170 | $serverList = self::getList($serviceName, $soaConfig); 171 | $key = "{$ip}_{$port}_{$type}"; 172 | if (!empty($serverList[$key])) { 173 | $serverList[$key] = self::$selector->success($serverList[$key]); 174 | self::reload($serviceName, $serverList, 0); 175 | } 176 | } 177 | 178 | /** 179 | * @param $serviceName 180 | * @param $ip 181 | * @param $port 182 | * @param $type 183 | * @throws SchedulerException 184 | * @throws \Exception 185 | * @desc 服务选择失败,回调处理 186 | */ 187 | public static function fail($serviceName, $ip, $port, $type) 188 | { 189 | $soaConfig = ZConfig::get('soa'); 190 | $serverList = self::getList($serviceName, $soaConfig); 191 | $key = "{$ip}_{$port}_{$type}"; 192 | if (!empty($serverList[$key])) { 193 | $serverList[$key] = self::$selector->fail($serverList[$key]); 194 | self::reload($serviceName, $serverList, 0); 195 | } 196 | 197 | return; 198 | 199 | } 200 | 201 | } -------------------------------------------------------------------------------- /ant-rpc/sdk/ConfigClient.php: -------------------------------------------------------------------------------- 1 | call('get', [ 37 | 'key' => $key, 38 | 'serviceName' => $serviceName 39 | ]); 40 | $body = $result->getBody(); 41 | $record = $body['data']['record']; 42 | if (empty($record)) { 43 | throw new ConfigException("record empty", -1); 44 | } 45 | if ($record['item'] !== $key) { 46 | throw new ConfigException("key error {$key} != {$record['item']}", -1); 47 | } 48 | if (is_array($record['value'])) { 49 | return $record['value']; 50 | } 51 | return json_decode($record['value'], true); 52 | } catch (\Exception $e) { 53 | if ($throw) { 54 | throw $e; 55 | } 56 | ConfigException::exceptionHandler($e); 57 | return false; 58 | } 59 | } 60 | 61 | public static function __callStatic($name, $arguments) 62 | { 63 | // TODO: Implement __callStatic() method. 64 | 65 | } 66 | } -------------------------------------------------------------------------------- /ant-rpc/sdk/HttpClient.php: -------------------------------------------------------------------------------- 1 | getMessage() . ']', $e->getCode()); 36 | } 37 | Scheduler::fail($serviceName, $ip, $port, $type); 38 | $retry--; 39 | return self::getService($serviceName, $timeOut, $config, $retry); 40 | } 41 | } 42 | 43 | /** 44 | * @param $sendArr 45 | * @return mixed 46 | */ 47 | public function pack($sendArr) 48 | { 49 | return $sendArr; 50 | } 51 | 52 | /** 53 | * @param $result 54 | * @return Result 55 | */ 56 | public function unpack($result) 57 | { 58 | 59 | list($header, $body) = explode("\r\n\r\n", $result, 2); 60 | $headerArr = explode("\r\n", $header); 61 | $headerList = []; 62 | foreach ($headerArr as $str) { 63 | list($key, $val) = explode(':', $str); 64 | $headerList[trim($key)] = trim($val); 65 | } 66 | if ($this->isDot) { 67 | $executeTime = microtime(true) - $this->startTime; 68 | MonitorClient::clientDot($this->api . DS . $this->method, $executeTime); 69 | } 70 | return new Result($headerList, json_decode($body, true)); 71 | } 72 | } -------------------------------------------------------------------------------- /ant-rpc/sdk/LoadService.php: -------------------------------------------------------------------------------- 1 | setApi('dot')->setDot(0)->call('service', 42 | [ 43 | 'serviceName' => ZConfig::getField('soa', 'serverName', ZConfig::get('project_name')), 44 | 'serviceIp' => $serverIp, 45 | 'servicePort' => ZConfig::getField('soa', 'serverPort', ZConfig::getField('socket', 'port')), 46 | 'api' => $api, 47 | 'time' => $time 48 | ] 49 | ); 50 | } catch (\Exception $e) { 51 | $model = Formater::exception($e); 52 | Log::info([\var_export($model, true)], 'exception'); 53 | } 54 | } 55 | 56 | /** 57 | * @param $api 58 | * @param $time 59 | * @throws \Exception 60 | * @desc 调用方耗时上线 61 | */ 62 | public static function clientDot($api, $time) 63 | { 64 | 65 | $serverIp = ZConfig::getField('soa', 'serverIp', ZConfig::getField('socket', 'host')); 66 | if ('0.0.0.0' == $serverIp) { 67 | $serverIp = Utils::getLocalIp(); 68 | } 69 | $params = [ 70 | 'serviceName' => ZConfig::getField('soa', 'serverName', ZConfig::get('project_name')), 71 | 'serviceIp' => $serverIp, 72 | 'servicePort' => ZConfig::getField('soa', 'serverPort', ZConfig::getField('socket', 'port')), 73 | 'api' => $api, 74 | 'time' => $time 75 | ]; 76 | Log::info($params, 'client_dot'); 77 | if (ZConfig::get('project_name') == Consts::MONITOR_SERVER_NAME || 78 | ZConfig::get('project_name') == Consts::REGISTER_SERVER_NAME 79 | ) { 80 | return; 81 | } 82 | try { 83 | $client = UdpClient::getService(Consts::MONITOR_SERVER_NAME); 84 | $client->setApi('dot')->setDot(0)->call('client', 85 | $params 86 | ); 87 | } catch (\Exception $e) { 88 | $model = Formater::exception($e); 89 | Log::info([\var_export($model, true)], 'exception'); 90 | } 91 | } 92 | 93 | /** 94 | * @param $api 95 | * @param $time 96 | * @throws \Exception 97 | * @desc task任务耗时 98 | */ 99 | public static function taskDot($api, $time) 100 | { 101 | if (ZConfig::get('project_name') == Consts::MONITOR_SERVER_NAME || 102 | ZConfig::get('project_name') == Consts::REGISTER_SERVER_NAME 103 | ) { 104 | return; 105 | } 106 | try { 107 | $client = UdpClient::getService(Consts::MONITOR_SERVER_NAME); 108 | $serverIp = ZConfig::getField('soa', 'serverIp', ZConfig::getField('socket', 'host')); 109 | if ('0.0.0.0' == $serverIp) { 110 | $serverIp = Utils::getLocalIp(); 111 | } 112 | $client->setApi('dot')->setDot(0)->call('task', 113 | [ 114 | 'serviceName' => ZConfig::getField('soa', 'serverName', ZConfig::get('project_name')), 115 | 'serviceIp' => $serverIp, 116 | 'servicePort' => ZConfig::getField('soa', 'serverPort', ZConfig::getField('socket', 'port')), 117 | 'api' => $api, 118 | 'time' => $time 119 | ] 120 | ); 121 | } catch (\Exception $e) { 122 | $model = Formater::exception($e); 123 | Log::info([\var_export($model, true)], 'exception'); 124 | } 125 | } 126 | } -------------------------------------------------------------------------------- /ant-rpc/sdk/TcpClient.php: -------------------------------------------------------------------------------- 1 | getMessage() . ']', $e->getCode()); 39 | } 40 | Scheduler::fail($serviceName, $ip, $port, $type); 41 | $retry--; 42 | return self::getService($serviceName, $timeOut, $config, $retry); 43 | } 44 | } 45 | 46 | public function pack($sendArr) 47 | { 48 | return packer\Factory::getInstance(ZConfig::getField('project', 'packer', 'Ant'))->pack(Request::getHeaders(), $sendArr); 49 | } 50 | 51 | /** 52 | * @param $result 53 | * @return \packer\Result 54 | * @throws \Exception 55 | */ 56 | public function unpack($result) 57 | { 58 | if ($this->isDot) { 59 | $executeTime = microtime(true) - $this->startTime; 60 | MonitorClient::clientDot($this->api . DS . $this->method, $executeTime); 61 | } 62 | return packer\Factory::getInstance(ZConfig::getField('project', 'packer', 'Ant'))->unpack($result); 63 | } 64 | 65 | /** 66 | * @param $method 67 | * @param array $params 68 | * @return \packer\Result 69 | * @throws \Exception 70 | */ 71 | public function call($method, $params = []) 72 | { 73 | Request::addHeaders([ 74 | 'X-Request-ServerName' => ZConfig::getField('soa', 'service_name', ZConfig::get('project_name')), 75 | 'X-Request-Key' => $this->key, 76 | 'X-Request-TimeOut' => $this->timeOut, 77 | ], false, true); 78 | $result = parent::call($method, $params); 79 | Log::info([$method, $params, $result], 'call'); 80 | return $result; 81 | } 82 | } -------------------------------------------------------------------------------- /ant-rpc/sdk/UdpClient.php: -------------------------------------------------------------------------------- 1 | getMessage() . ']', $e->getCode()); 39 | } 40 | Scheduler::fail($serviceName, $ip, $port, $type); 41 | $retry--; 42 | return self::getService($serviceName, $timeOut, $config, $retry); 43 | } 44 | } 45 | 46 | public function pack($sendArr) 47 | { 48 | return packer\Factory::getInstance(ZConfig::getField('project', 'packer', 'Ant'))->pack(Request::getHeaders(), $sendArr); 49 | } 50 | 51 | /** 52 | * @param $result 53 | * @return \packer\Result 54 | * @throws \Exception 55 | */ 56 | public function unpack($result) 57 | { 58 | if ($this->isDot) { 59 | $executeTime = microtime(true) - $this->startTime; 60 | MonitorClient::clientDot($this->api . DS . $this->method, $executeTime); 61 | } 62 | return packer\Factory::getInstance(ZConfig::getField('project', 'packer', 'Ant'))->unpack(null); 63 | } 64 | 65 | /** 66 | * @param $method 67 | * @param array $params 68 | * @return \packer\Result 69 | * @throws \Exception 70 | */ 71 | public function call($method, $params = []) 72 | { 73 | Request::addHeaders([ 74 | 'X-Request-ServerName' => ZConfig::getField('soa', 'service_name', ZConfig::get('project_name')), 75 | 'X-Request-Key' => $this->key, 76 | 'X-Request-TimeOut' => $this->timeOut, 77 | ], false, true); 78 | $result = parent::call($method, $params); 79 | Log::info([$method, $params, $result], 'udp_call'); 80 | return $result; 81 | } 82 | } -------------------------------------------------------------------------------- /ant-rpc/sdk/antClient.go: -------------------------------------------------------------------------------- 1 | package antClient 2 | 3 | import ( 4 | "net" 5 | "bytes" 6 | "encoding/binary" 7 | "io" 8 | "fmt" 9 | "strconv" 10 | ) 11 | 12 | type DClient struct { 13 | Host string 14 | Port int 15 | Api string 16 | Sync bool 17 | CtrlName string 18 | MethodName string 19 | HeaderLen int 20 | Conn net.Conn 21 | Chan chan []string 22 | Debug bool 23 | } 24 | 25 | func GetClient(host string, port int) *DClient { 26 | c := make(chan []string) 27 | cli := &DClient{ 28 | host, 29 | port, 30 | "main", 31 | true, 32 | "a", 33 | "m", 34 | 4, 35 | nil, 36 | c, 37 | false, 38 | } 39 | cli.Connect() 40 | return cli 41 | } 42 | 43 | func (cli *DClient) SetApi(api string) *DClient { 44 | cli.Api = api 45 | return cli 46 | } 47 | 48 | func (cli *DClient) NoSync() *DClient { 49 | cli.Sync = false 50 | return cli 51 | } 52 | 53 | func (cli *DClient) SetDebug() *DClient { 54 | cli.Debug = true 55 | return cli 56 | } 57 | 58 | func (cli *DClient) Pack(_data string) []byte { 59 | buf := new(bytes.Buffer) 60 | var data = []interface{}{ 61 | uint32(len(_data)), 62 | []byte(_data), 63 | } 64 | for _, v := range data { 65 | err := binary.Write(buf, binary.BigEndian, v) 66 | if nil != err { 67 | str := "ERROR: pack " + _data + "error :" + err.Error() 68 | panic(str) 69 | } 70 | } 71 | return buf.Bytes() 72 | } 73 | 74 | func (cli *DClient) Unpack(b []byte) ([]string, []byte, bool) { 75 | dlen := len(b); 76 | data := make([]string, 0) 77 | ok := false 78 | start := 0 79 | var b_buf *bytes.Buffer 80 | var x int32 81 | for { 82 | b_buf = bytes.NewBuffer(b[start:cli.HeaderLen]) 83 | binary.Read(b_buf, binary.BigEndian, &x) 84 | //x = int(x) 85 | x += int32(cli.HeaderLen) 86 | start += int(x) 87 | if int(x) == dlen { 88 | //正好一个完整包 89 | data = append(data, string(b[start - int(x) + cli.HeaderLen:int(x)])) 90 | ok = true; 91 | break 92 | } 93 | 94 | if int(x) > dlen { 95 | //不足一个包 96 | start -= int(x) 97 | break; 98 | } 99 | ok = true 100 | dlen -= int(x) 101 | data = append(data, string(b[start - int(x) + cli.HeaderLen:int(x)])) 102 | } 103 | return data, b[start:], ok 104 | } 105 | 106 | func (cli *DClient) Connect() { 107 | conn, err := net.Dial("tcp", cli.Host+":"+strconv.Itoa(cli.Port)) 108 | if nil != err { 109 | panic("connect server error") 110 | } 111 | cli.Conn = conn 112 | } 113 | 114 | func (cli *DClient) Send(data string) (int) { 115 | wrote := cli.Pack(data); 116 | _slen, err := cli.Conn.Write(wrote) 117 | if nil != err { 118 | println(err.Error()) 119 | } 120 | return _slen 121 | } 122 | 123 | func (cli *DClient) Recv() { 124 | var b [4096]byte 125 | var ret bytes.Buffer 126 | for { 127 | rlen, err := cli.Conn.Read(b[0:]) 128 | if nil == err { 129 | if rlen > 0 { 130 | ret.Write(b[:rlen]) 131 | result, more, ok := cli.Unpack(ret.Bytes()) 132 | if (ok) { 133 | cli.Chan <- result 134 | } 135 | if len(more) > 0 { 136 | ret.Reset() 137 | ret.Write(more) 138 | } 139 | 140 | } 141 | } else { 142 | if (err == io.EOF) { 143 | 144 | } else { 145 | break; 146 | } 147 | } 148 | } 149 | } 150 | 151 | func (cli *DClient) Call(method string, data map[string]string) []string { 152 | var sendData string; 153 | _recv := "0" 154 | if (cli.Sync) { 155 | _recv = "1" 156 | } 157 | sendData = "{\"_recv\":" + _recv + "," 158 | for k, v := range data { 159 | sendData += "\"" + k + "\":\"" + v + "\"," 160 | } 161 | sendData += " \"" + cli.CtrlName + "\":\"" + cli.Api + "\", \"" + cli.MethodName + "\":\"" + method + "\"}" 162 | cli.Log("send:%s", sendData) 163 | cli.Send(sendData) 164 | go cli.Recv() 165 | result := <-cli.Chan 166 | return result 167 | } 168 | 169 | func (cli *DClient) Log(format string, a ...interface{}) { 170 | if cli.Debug { 171 | fmt.Printf(format, a ...) 172 | } 173 | } -------------------------------------------------------------------------------- /example/demo.php: -------------------------------------------------------------------------------- 1 | call('test'); --------------------------------------------------------------------------------