大数据分布式架构盛行时代的程序员面试,常常遇到分布式架构,RPC,本文的主角是RPC,英文名为Remote Procedure Call,翻译过来为“远程过程调用”。主流的平台中都支持各种远程调用技术,以满足分布式系统架构中不同的系统之间的远程通信和相互调用。远程调用的应用场景极其广泛,实现的方式也各式各样。作为WEB开发中主力军,PHP也是支持RPC的,那么如何原生实现呢?
PHP原生实现RPC,主要用到以下这6个函数:
stream_socket_server、stream_socket_client、stream_socket_accept、fread、fwrite、
fclose
rpc由于服务端和客户端组成,下面让我们一起来实现服务端和客户端。
开发环境或者工具:PHP8.0+Visual Studio Code
先写服务端:
$rpc_server = stream_socket_server("tcp://127.0.0.1:6661",$err_no,$err_msg);
if(!$rpc_server)
{
echo "代码异常:".$err_no.",信息异常:".$err_msg;
exit();
}
while(true){
$result = [];//定义返回结果数组
try{
$buff = stream_socket_accept($rpc_server);
$data = fread($buff,2048);//读取客户端选数据
$json = json_decode($data,true);//转换客户端的json数据
$class = $json['class'];//客户端需要访问的类
$file = $class.".php";
require_once $file;//包含进来
if(!file_exists($file)){//如果文件不存在
throw new Exception('文件不存在','404');
}
$method = $json['method'];//客户端需要访问的方法
$obj = new $class();//实例化对象
$rpc_server_data = $obj->$method($json['can_shu']);//调用方法
$result['code'] = 1;//成功返回1
$result['data'] = $rpc_server_data;//返回数据
$result['msg'] = "请求成功";
$result_data = json_encode($result);//转换为json数据
fwrite($buff,$result_data);
fclose($rpc_server);//关闭资源
}catch(Excepiton $e){
$result['code'] = $e->getCode();//失败返回
$result['data'] = $rpc_server_data;//返回空数据
$result['msg'] = $e->getMessage();//失败返回
$result_data = json_encode($result);//转换为json数据
fwrite($buff,$result);
fclose($rpc_server);//关闭资源
}
编写服务端辅助文件login.php:
class login
{
public function get_account($number=''){
return "编程自学".$number;
}
}
接着写客户端:
$rpc_client = stream_socket_client("tcp://127.0.0.1:6661",$err_no,$err_msg);
if(!$rpc_client)
{
echo "代码异常:".$err_no.",信息异常:".$err_msg;
exit();
}
$c_data['class'] = "login";
$c_data['method'] = "get_account";
$c_data['can_shu'] = "8";
$rpc_data = json_encode($c_data);
fwrite($rpc_client,$rpc_data);//发送给服务端
$rpc_server_data = fread($rpc_client,2048);//读取服务端数据
$sever_json = json_decode($rpc_server_data);//解码json数据
fclose($rpc_client);//关闭资源
var_dump($sever_json);//打印
启动服务端:php rpc_server.php
然后启动客户端:php rpc_client.php,可以看到下面效果:
改造成从浏览器中打开:
//rpc:
public function testRpc()
{
$rpc_client = stream_socket_client("tcp://127.0.0.1:6661",$err_no,$err_msg);
if(!$rpc_client)
{
echo "代码异常:".$err_no.",信息异常:".$err_msg;
exit();
}
$c_data['class'] = $_GET['c'];
$c_data['method'] = $_GET['m'];
$c_data['can_shu'] = $_GET['n'];
$rpc_data = json_encode($c_data);
fwrite($rpc_client,$rpc_data);//发送给服务端
$rpc_server_data = fread($rpc_client,2048);//读取服务端数据
$sever_json = json_decode($rpc_server_data,true);//解码json数据
fclose($rpc_client);//关闭资源
dd($sever_json);//打印
}
启动服务,在浏览器中打开http://127.0.0.1:8000/test-rpc?c=login&m=get_account&n=8
可以看到下面效果:
这一节就介绍到这里了。