son rpc 是一種以json爲消息格式的遠程調用服務,它是一套容許運行在不一樣操做系統、不一樣環境的程序實現基於Internet過程調用的規範和一系列的實現。這種遠程過程調用能夠使用http做爲傳輸協議,也能夠使用其它傳輸協議,傳輸的內容是json消息體。
下面咱們code一套基於php的rpc框架,此框架中包含rpc的服務端server,和應用端client;
(一)PHP服務端RPCserver jsonRPCServer.phpjavascript
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.phpphp
<?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
複製代碼 代碼以下:java
<?php
require_once 'jsonRPCServer.php';
複製代碼 代碼以下:json
// member 爲測試類
require 'member.php';
// 服務端調用
$myExample = new member();
// 注入實例
jsonRPCServer::handle($myExample)
or print 'no request';
?>
(2)測試類文件,member.phpapp
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"; }