当前位置: 首页 > 后端技术 > PHP

PHP实现简单的RPC

时间:2023-03-29 15:19:50 PHP

1。什么是rpcRPC全称为RemoteProcedureCall,译为“远程过程调用”。目前主流平台都支持各种远程调用技术,以满足分布式系统架构下不同系统之间的远程通信和相互调用。远程调用的应用场景极其广泛,实现方式也是五花八门。2.从通信协议层面基于HTTP协议(如基于文本的SOAP(XML)、Rest(JSON)、基于二进制的Hessian(二进制))基于TCP协议(通常借助高性能网络Mina和Netty等框架)3.从不同的开发语言和平台层面,单一语言或平台特定的通信技术(如Java平台的RMI,.NET平台的Remoting)支持跨平台通信技术(如如HTTPRest,Thrift等)4.从调用过程来看,同步通信调用(synchronousRPC)异步通信调用(MQ,异步RPC)5.远程数据共享的几种常用通信方式(例如:共享远程文件,共享数据库等实现不同系统之间的通信)消息队列RPC(remoteProcesscall)6.php实现了一个简单的rpc目录结构rpcserver'',//ipaddress,column出来的目的是为了看这个变量存储的信息'port'=>'',//port'path'=>''//服务目录];/***User:yuzhao*CreateTime:2018/11/1612:14AM*@vararray*描述:该类常用配置*/private$config=['real_path'=>'','max_size'=>2048//最大接收数据大小];/***用户:yuzhao*创建时间:2018/11/15pm11:50*@varnul*描述:*/private$server=null;/***Rpc构造函数。*/publicfunction__construct($params){$this->check();$this->init($params);}/***用户:yuzhao*创建时间:2018/11/1612:0am*描述:需要验证*/privatefunctioncheck(){$this->serverPath();}/***User:yuzhao*CreateTime:2018/11/1511:48pm*Description:初始化必要的参数*/privatefunctioninit($params){//初始化传入的参数$this->params=$params;//创建tcpsocket服务$this->createServer();}/***用户:yuzhao*创建时间:2018/11/1612:0am*描述:创建tcpsocket服务*/privatefunctioncreateServer(){$this->server=stream_socket_server("tcp://{$this->params['host']}:{$this->params['port']}",$errno,$errstr);如果(!$this->server)exit([$errno,$errstr]);}/***用户:yuzhao*创建时间:2018/11/1511:57pm*描述:rpc服务目录*/publicfunctionserverPath(){$path=$this->params['path'];$realPath=realpath(__DIR__.$path);如果($realPath===false||!file_exists($realPath)){exit("{$path}error!");}$this->config['real_path']=$realPath;}/***用户:yuzhao*创建时间:2018/11/1511:51pm*描述:返回当前对象*/publicstaticfunctioninstance($params){returnnewRpcServer($params);}/***用户:yuzhao*创建时间:2018/11/1612:06AM*描述:运行*/publicfunctionrun(){while(true){$client=stream_socket_accept($this->server);if($client){echo"新连接\n";$buf=fread($client,$this->config['max_size']);print_r('收到的原始数据:'.$buf."\n");//自定义协议的目的是获取类方法和参数(可以改为自定义)$this->parseProtocol($buf,$class,$method,$params);//执行方法$this->execMethod($client,$class,$method,$params);//关闭客户端fclose($client);echo"关闭连接\n";}}}/***用户:yuzhao*创建时间:2018/11/1612:19AM*@param$class*@param$method*@param$params*描述:执行方法*/privatefunctionexecMethod($client,$class,$method,$params){if($class&&$method){//将首字母转换为大写$class=ucfirst($class);$file=$this->params['path'].'/'。$类。'.php';//判断文件是否存在,存在则引入文件if(file_exists($file)){require_once$file;//实例化类并调用客户端指定的方法$obj=new$class();//如果有参数,则传入指定的参数if(!$params){$data=$obj->$method();}else{$data=$obj->$method($params);}//打包数据$this->packProtocol($data);//把运行后的结果返回给客户端fwrite($client,$data);}}else{fwrite($client,'类或方法错误');}}/***用户:yuzhao*CreateTime:2018/11/16at12am:10*Description:ParseProtocol*/privatefunctionparseProtocol($buf,&$class,&$method,&$params){$buf=json_decode($buf,true);$class=$buf['class'];$method=$buf['方法'];$params=$buf['params'];}/***用户:yuzhao*创建时间:2018/11/16AM12:30*@param$data*描述:打包协议*/privatefunctionpackProtocol(&$data){$data=json_encode($data,JSON_UNESCAPED_UNICODE);}}RpcServer::instance(['host'=>'127.0.0.1','port'=>8888,'path'=>'./api'])->run();rpcclienturlInfo=parse_url($url);}/***用户:yuzhao*创建时间:2018/11/16AM12:2*描述:返回当前对象*/publicstaticfunctioninstance($url){returnnewRpcClient($url);}publicfunction__call($name,$arguments){//TODO:实现__call()方法。//创建客户端$client=stream_socket_client("tcp://{$this->urlInfo['host']}:{$this->urlInfo['port']}",$errno,$errstr);如果(!$client){exit("{$errno}:{$errstr}\n");}$data=['类'=>;basename($this->urlInfo['path']),'method'=>$name,'params'=>$arguments];//发送我们的自定义协议数据到服务器fwrite($client,json_encode($data));//从服务器读取数据$data=fread($client,2048);//关闭客户端fclose($client);返回$数据;}}$cli=newRpcClient('http://127.0.0.1:8888/test');echo$cli->tuzisir1()."\n";echo$cli->tuzisir2(array('name'=>'tuzisir','年龄'=>23));服务文件