在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
RPC 定义RPC(Remote Procedure Call)即远程过程调用,指被调用方法的具体实现不在程序运行本地,而是在别的某个地方。主要应用于不同的系统之间的远程通信和相互调用。 如 A 调用 B 提供的 remoteAdd 方法:
有些远程调用选择比较底层的 socket 协议,有些远程调用选择比较上层的 HTTP 协议。 远程调用的好处:
这里使用 PHP Socket 来创建一个服务端和客户端,目录结构如下: 服务端<?php class RpcServer { protected $server = null; public function __construct($host, $port, $path) { // 创建一个 Socket 服务 if(($this->server = socket_create(AF_INET,SOCK_STREAM,SOL_TCP)) < 0) { exit("socket_create() 失败的原因是:".socket_strerror($this->server)."\n"); } if(($ret = socket_bind($this->server,$host,$port)) < 0) { exit("socket_bind() 失败的原因是:".socket_strerror($ret)."\n"); } if(($ret = socket_listen($this->server,3)) < 0) { exit("socket_listen() 失败的原因是:".socket_strerror($ret)."\n"); } // 判断 RPC 服务目录是否存在 $realPath = realpath(__DIR__ . $path); if ($realPath === false || !file_exists($realPath)) { exit("{$path} error \n"); } do { $client = socket_accept($this->server); if($client) { // 一次性读取 $buf = socket_read($client, 8024); echo $buf; //解析客户端发送过来的协议 $classRet = preg_match('/Rpc-Class:\s(.*);\r\n/i', $buf, $class); $methodRet = preg_match('/Rpc-Method:\s(.*);\r\n/i', $buf, $method); $paramsRet = preg_match('/Rpc-Params:\s(.*);\r\n/i', $buf, $params); if($classRet && $methodRet) { $class = ucfirst($class[1]); $method = $method[1]; $params = json_decode($params[1], true); $file = $realPath . '/' . $class . '.php'; // 类文件需要和类名一致 $data = ''; // 执行结果 // 判断类文件是否存在 if(file_exists($file)) { // 引入类文件 require_once $file; // 实例化类 $rfc_obj = new ReflectionClass($class); // 判断该类指定方法是否存在 if($rfc_obj->hasMethod($method)) { // 执行类方法 $rfc_method = $rfc_obj->getMethod($method); $data = $rfc_method->invokeArgs($rfc_obj->newInstance(), [$params]); } else { socket_write($client, 'method error'); } //把运行后的结果返回给客户端 socket_write($client, $data); } } else { socket_write($client, 'class or method error'); } // 关闭客户端 socket_close($client); } }while(true); } public function __destruct() { socket_close($this->server); } } new RpcServer('127.0.0.1',8080,'./service'); 客户端<?php class RpcClient { protected $client = null; protected $url_info = []; // 远程调用 URL 组成部分 public function __construct($url) { // 解析 URL $this->url_info = parse_url($url); } public function __call($name, $arguments) { // 创建一个客户端 $this->client = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if(!$this->client) { exit('socket_create() 失败'); } socket_connect($this->client, $this->url_info['host'], $this->url_info['port']); // 传递调用的类名 $class = basename($this->url_info['path']); // 传递调用的参数 $args = ''; if(isset($arguments[0])) { $args = json_encode($arguments[0]); } // 向服务端发送我们自定义的协议数据 $proto = "Rpc-Class: {$class};".PHP_EOL ."Rpc-Method: {$name};".PHP_EOL ."Rpc-Params: {$args};".PHP_EOL; socket_write($this->client, $proto); // 读取服务端传来的数据 $buf = socket_read($this->client, 8024); socket_close($this->client); return $buf; } } $rpcClient = new RpcClient('http://127.0.0.1:8080/news'); echo $rpcClient->display(['title'=>'txl']); echo $rpcClient->display(['title'=>'hello world']); 服务类 News<?php class News { public function display($data) { return json_encode(['result'=>"News display(), title is {$data['title']}"]); } } 运行测试: Client Server 到此这篇关于PHP创建简单RPC服务案例详解的文章就介绍到这了,更多相关PHP创建简单RPC服务内容请搜索极客世界以前的文章或继续浏览下面的相关文章希望大家以后多多支持极客世界! |
2022-07-29
2022-08-17
2022-11-06
2022-07-30
2022-08-17
请发表评论