1 <?php2 /**3 * User: yuzhao4 * CreateTime: 2018/11/15 下午11:465 * Description: Rpc服务端6 */
7 classRpcServer {8
9 /**10 * User: yuzhao11 * CreateTime: 2018/11/15 下午11:5112 * @var array13 * Description: 此类的基本配置14 */
15 private $params =[16 'host' => '', //ip地址,列出来的目的是为了友好看出来此变量中存储的信息
17 'port' => '', //端口
18 'path' => '' //服务目录
19 ];20 phper在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,
包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,
laravel,YII2,Redis,Swoole、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要的请点击(→)我的官方群
21 /**22 * User: yuzhao23 * CreateTime: 2018/11/16 上午12:1424 * @var array25 * Description: 本类常用配置26 */
27 private $config =[28 'real_path' => '',
29 'max_size' => 2048 //最大接收数据大小
30 ];31
32 /**33 * User: yuzhao34 * CreateTime: 2018/11/15 下午11:5035 * @var nul36 * Description:37 */
38 private $server = null;39
40 /**41 * Rpc constructor.42 */
43 public function __construct($params)44 {45 $this->check();46 $this->init($params);47 }48
49 /**50 * User: yuzhao51 * CreateTime: 2018/11/16 上午12:052 * Description: 必要验证53 */
54 private functioncheck() {55 $this->serverPath();56 }57
58 /**59 * User: yuzhao60 * CreateTime: 2018/11/15 下午11:4861 * Description: 初始化必要参数62 */
63 private function init($params) {64 //将传递过来的参数初始化
65 $this->params = $params;66 //创建tcpsocket服务
67 $this->createServer();68 }69
70 /**71 * User: yuzhao72 * CreateTime: 2018/11/16 上午12:073 * Description: 创建tcpsocket服务74
75 */
76 private functioncreateServer() {77 $this->server = stream_socket_server("tcp://{$this->params['host']}:{$this->params['port']}", $errno,$errstr);78 if (!$this->server) exit([79 $errno,$errstr
80 ]);81 }82
83 /**84 * User: yuzhao85 * CreateTime: 2018/11/15 下午11:5786 * Description: rpc服务目录87 */
88 public functionserverPath() {89 $path = $this->params['path'];90 $realPath = realpath(__DIR__ . $path);91 if ($realPath === false ||!file_exists($realPath)) {92 exit("{$path} error!");93 }94 $this->config['real_path'] = $realPath;95 }96
97 /**98 * User: yuzhao99 * CreateTime: 2018/11/15 下午11:51100 * Description: 返回当前对象101 */
102 public static function instance($params) {103 return new RpcServer($params);104 }105
106 /**107 * User: yuzhao108 * CreateTime: 2018/11/16 上午12:06109 * Description: 运行110 */
111 public functionrun() {112 while (true) {113 $client = stream_socket_accept($this->server);114 if ($client) {115 echo "有新连接\n";116 $buf = fread($client, $this->config['max_size']);117 print_r('接收到的原始数据:'.$buf."\n");118 //自定义协议目的是拿到类方法和参数(可改成自己定义的)
119 $this->parseProtocol($buf,$class, $method,$params);120 //执行方法
121 $this->execMethod($client, $class, $method, $params);122 //关闭客户端
123 fclose($client);124 echo "关闭了连接\n";125 }126 }127 }128
129 /**130 * User: yuzhao131 * CreateTime: 2018/11/16 上午12:19132 * @param $class133 * @param $method134 * @param $params135 * Description: 执行方法136 */
137 private function execMethod($client, $class, $method, $params) {138 if($class && $method) {139 //首字母转为大写
140 $class = ucfirst($class);141 $file = $this->params['path'] . '/' . $class . '.php';142 //判断文件是否存在,如果有,则引入文件
143 if(file_exists($file)) {144 require_once $file;145 //实例化类,并调用客户端指定的方法
146 $obj = new $class();147 //如果有参数,则传入指定参数
148 if(!$params) {149 $data = $obj->$method();150 } else{151 $data = $obj->$method($params);152 }153 //打包数据
154 $this->packProtocol($data);155 //把运行后的结果返回给客户端
156 fwrite($client, $data);157 }158 } else{159 fwrite($client, 'class or method error');160 }161 }162
163 /**164 * User: yuzhao165 * CreateTime: 2018/11/16 上午12:10166 * Description: 解析协议167 */
168 private function parseProtocol($buf, &$class, &$method, &$params) {169 $buf = json_decode($buf, true);170 $class = $buf['class'];171 $method = $buf['method'];172 $params = $buf['params'];173 }174
175 /**176 * User: yuzhao177 * CreateTime: 2018/11/16 上午12:30178 * @param $data179 * Description: 打包协议180 */
181 private function packProtocol(&$data) {182 $data = json_encode($data,JSON_UNESCAPED_UNICODE);183 }184
185 }186
187 RpcServer::instance([188 'host' => '127.0.0.1',
189 'port' => 8888,
190 'path' => './api'
191 ])->run();