├── .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 |
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');
--------------------------------------------------------------------------------