rpc 定义 RPC(Remote Procedure Call)即远程过程调用,指被调用方法的具体实现不在程序运行本地,而是在别的某个地方。主要应用于不同的系统之间的远程通信和相互
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']);
<?php
class News {
public function display($data)
{
return json_encode(['result'=>"News display(), title is {$data['title']}"]);
}
}
运行测试:
Client
Server
到此这篇关于PHP创建简单RPC服务案例详解的文章就介绍到这了,更多相关PHP创建简单RPC服务内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: PHP创建简单RPC服务案例详解
本文链接: https://lsjlt.com/news/134822.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0