php實現(xiàn)的一個簡單json rpc框架實例

字號:


    這篇文章主要介紹了php實現(xiàn)的一個簡單json rpc框架實例,本文給出了RPC服務(wù)端和客戶端代碼以及應(yīng)用實例,需要的朋友可以參考下
    json rpc 是一種以json為消息格式的遠程調(diào)用服務(wù),它是一套允許運行在不同操作系統(tǒng)、不同環(huán)境的程序?qū)崿F(xiàn)基于Internet過程調(diào)用的規(guī)范和一系列的實現(xiàn)。這種遠程過程調(diào)用可以使用http作為傳輸協(xié)議,也可以使用其它傳輸協(xié)議,傳輸?shù)膬?nèi)容是json消息體。
    下面我們code一套基于php的rpc框架,此框架中包含rpc的服務(wù)端server,和應(yīng)用端client;
    (一)PHP服務(wù)端RPCserver jsonRPCServer.php
    代碼如下:
    class jsonRPCServer {
    /**
    *處理一個request類,這個類中綁定了一些請求參數(shù)
    * @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);
    // 執(zhí)行請求類中的接口
    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
    復(fù)制代碼 代碼如下:
    <?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 *****'."nn";
    $opts = array ('http' => array (
    'method' => 'POST',
    'header' => 'Content-type: application/json',
    'content' => $request
    ));
    // 關(guān)鍵幾部
    $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);
    }
    // 輸出調(diào)試信息
    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;
    }
    }
    }
    ?>
    (三) 應(yīng)用實例
    (1)服務(wù)端 server.php
    代碼如下:
    <?php
    require_once 'jsonRPCServer.php';
    代碼如下:
    // member 為測試類
    require 'member.php';
    // 服務(wù)端調(diào)用
    $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);
    // 客戶端調(diào)用
    try {
    $name = $myExample->getName();
    echo $name ;
    } catch (Exception $e) {
    echo nl2br($e->getMessage()).'<br />'."n";
    }