json rpc 是一种以json为消息格式的远程调用服务,它是一套允许运行在不同操作系统、不同环境的程序实现基于Internet过程调用的规范和一系列的实现。这 种远程过程调用可以使用http作为传输协议,也可以使用其它传输协议,传输的内容是json消息体。

下面我们code一套基于php的rpc框架,此框架中包含rpc的服务端server,和应用端client;

(一)PHP服务端RPCserver jsonRPCServer.php

代码如下:

class jsonRPCServer {
  
 /**
  
 *处理一个request类,这个类中绑定了一些请求参数
  
 * @param object $object
  
 * @return boolean
  
 */
  
 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 ( ‘id’=> $request[‘id’],’result’=> $result,’error’=> NULL );
  
 } else {
  
 $response = array ( ‘id’=> $request[‘id’], ‘result’=> NULL,
  
 ‘error’ => ‘unknown method or incorrect parameters’ );}
  
 } catch (Exception $e) {
  
 $response = array (‘id’ => $request[‘id’],’result’ => NULL, ‘error’ =>$e->getMessage());
  
 }
  
 // json 格式输出
  
 if (!empty($request[‘id’])) { // notifications don’t want response
  
 header(‘content-type: text/javascript’);
  
 echo json_encode($response);
  
 }
  
 return true;
  
 }
  
 }

(二)Rpc客户端,jsonRPCClient.php

代码如下:

<?php
  
 /*
  
 */
  
 class jsonRPCClient {    private $debug;
  
 private $url;
  
 // 请求id
  
 private $id;
  
 private $notification = false;
  
 /**
  
 * @param $url
  
 * @param bool $debug
  
 */
  
 public function __construct($url,$debug = false) {
  
 // server URL
  
 $this->url = $url;
  
 // proxy
  
 empty($proxy) ? $this->proxy = ” : $this->proxy = $proxy;
  
 // debug state
  
 empty($debug) ? $this->debug = false : $this->debug = true;
  
 // message id
  
 $this->id = 1;
  
 }/**
  
 *
  
 * @param boolean $notification
  
 */
  
 public function setRPCNotification($notification) {
  
 empty($notification) ? $this->notification = false  : $this->notification = 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’);
  
 }if ($this->notification) {
  
 $currentId = NULL;
  
 } else {
  
 $currentId = $this->id;
  
 } 
  // 拼装成一个request请求
 $request = array(  ‘method’ => $method,  ‘params’ => $params,’id’ => $currentId);
 $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));
 }
 // 检验response信息
 if (!$this->notification) {
 // check
 if ($response[‘id’] != $currentId) {
 throw new Exception(‘Incorrect response id (request id: ‘.$currentId.’, response id: ‘.$response[‘id’].’)’);
 }
 if (!is_null($response[‘error’])) {
 throw new Exception(‘Request error: ‘.$response[‘error’]);
 }
 return $response[‘result’];} else {
 return true;
 }
 }
 }
 ?>

(三) 应用实例
(1)服务端 server.php

代码如下:

<?php
  
 require_once ‘jsonRPCServer.php’;

代码如下:

// member 为测试类
  
 require ‘member.php’;
  
 // 服务端调用
  
 $myExample = new member();
  
 // 注入实例
  
 jsonRPCServer::handle($myExample)
  
 or print ‘no request’;
  
 ?>

(2)测试类文件,member.php

代码如下:

class member{
  
 public function getName(){
  
 return ‘hello word ‘ ;  // 返回字符串
  
 }
  
 }

(3)客户端 client.php

代码如下:

require_once ‘jsonRPCClient.php’;$url = ‘http://localhost/rpc/server.php’;
  
 $myExample = new jsonRPCClient($url);// 客户端调用
  
 try {
  
 $name = $myExample->getName();
  
 echo $name ;
  
 } catch (Exception $e) {
  
 echo nl2br($e->getMessage()).'<br />’.”\n”;
  
 }

下载地址

提取密码:f8wq

附录:
thinkphp的rpc介绍
http://document.thinkphp.cn/manual_3_2.html#rpc