RPC(Remote Procedure Call
Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。
一、PHP服务端
server.php文件源码:
// member 为测试类(可拆开)
class member{
public function getName($name){
return 'please click '.$name ; // 返回字符串
}
}
class jsonRPCServer {
public static function handle($object) {
// 判断是否是一个rpc json请求
if ($_SERVER['REQUEST_METHOD'] != 'POST' || empty($_SERVER['CONTENT_TYPE'])
|| $_SERVER['CONTENT_TYPE'] != 'application/json') {
return false;
}
// reads the input data
$request = json_decode(file_get_contents('php://input'),true);
// 执行请求类中的接口
try {
if ($result = @call_user_func_array(array($object,$request['method']),$request['params'])) {
$response = array ('result'=> $result, 'error'=> NULL);
} else {
$response = array ('result'=> NULL, 'error' => 'unknown method or incorrect parameters');
}
} catch (Exception $e) {
$response = array ('result' => NULL, 'error' =>$e->getMessage());
}
header('content-type: text/javascript');
echo json_encode($response);
return true;
}
}
// 注入实例
$myExample = new member();
jsonRPCServer::handle($myExample) or print 'no request';
二、PHP客户端
jsonRPCClient.php 文件源码:
/*
* more:webyang.net
*/
class jsonRPCClient {
private $debug;
private $url;
/**
* @param $url
* @param bool $debug
*/
public function __construct($url,$debug = false) {
$this->url = $url;
empty($debug) ? $this->debug = false : $this->debug = true;
}
/**
* @param $method
* @param $params
* @return bool
* @throws Exception
*/
public function __call($method,$params) {
// 检验request信息
if (!is_scalar($method)) {
throw new Exception('Method name has no scalar value');
}
if (is_array($params)) {
$params = array_values($params);
} else {
throw new Exception('Params must be given as array');
}
// 拼装成一个request请求
$request = array('method' => $method, 'params' => $params);
$request = json_encode($request);
$this->debug && $this->debug.='***** Request *****'."\n".$request."\n".'***** End Of request *****'."\n\n";
$opts = array (
'http' => array (
'method' => 'POST',
'header' => 'Content-type: application/json',
'content' => $request
)
);
$context = stream_context_create($opts);
if ($result = file_get_contents($this->url, false, $context)) {
$response = json_decode($result, true);
} else {
throw new Exception('Unable to connect to '.$this->url);
}
// 输出调试信息
if ($this->debug) {
echo nl2br(($this->debug));
}
if (!is_null($response['error'])) {
throw new Exception('Request error: '.$response['error']);
}
return $response['result'];
}
}
client.php 文件源码:
require_once 'jsonRPCClient.php';
//服务端地址
$url = 'http://webyang.net/server.php';
$myExample = new jsonRPCClient($url);
// 客户端调用
try {
$name = $myExample->getName("webyang.net");
echo $name ;
} catch (Exception $e) {
echo nl2br($e->getMessage()).'
'."\n";
}
访问client.php,调用服务端的方法。