php实现的一个简单json rpc框架实例


Posted in PHP onMarch 30, 2015

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";

}
PHP 相关文章推荐
最小化数据传输――在客户端存储数据
Oct 09 PHP
怎么样可以把 phpinfo()屏蔽掉?
Nov 24 PHP
通过PHP CLI实现简单的数据库实时监控调度
Jul 01 PHP
PHP小技巧之JS和CSS优化工具Minify的使用方法
May 19 PHP
ThinkPHP CURD方法之page方法详解
Jun 18 PHP
php防止伪造数据从地址栏URL提交的方法
Aug 24 PHP
php基于表单密码验证与HTTP验证用法实例
Jan 06 PHP
学习php设计模式 php实现抽象工厂模式
Dec 07 PHP
Mac版PhpStorm之XAMPP整合apache服务器配置的图文教程详解
Oct 13 PHP
PHP使用PhpSpreadsheet操作Excel实例详解
Mar 26 PHP
PHP 实现 WebSocket 协议原理与应用详解
Apr 22 PHP
PHP常用header头定义代码示例汇总
Aug 29 PHP
php实现读取内存顺序号
Mar 29 #PHP
php实现插入排序
Mar 29 #PHP
php实现插入数组但不影响原有顺序的方法
Mar 27 #PHP
WordPress自定义时间显示格式
Mar 27 #PHP
在php和MySql中计算时间差的方法详解
Mar 27 #PHP
PHP连接access数据库
Mar 27 #PHP
使用新浪微博API的OAuth认证发布微博实例
Mar 27 #PHP
You might like
PHP中的日期处理方法集锦
2007/01/02 PHP
采用ThinkPHP中F方法实现快速缓存实例
2014/06/13 PHP
判断页面是关闭还是刷新的js代码
2007/01/28 Javascript
一组JS创建和操作表格的函数集合
2009/05/07 Javascript
javascript代码编写需要注意的7个小细节小结
2011/09/21 Javascript
jquery.mobile 共同布局遇到的问题小结
2015/02/10 Javascript
Avalonjs 实现简单购物车功能(实例代码)
2017/02/07 Javascript
纯js实现html转pdf的简单实例(推荐)
2017/02/16 Javascript
兼容浏览器的js事件绑定函数(详解)
2017/05/09 Javascript
Node.js 使用流实现读写同步边读边写功能
2017/09/11 Javascript
angular4实现tab栏切换的方法示例
2017/10/21 Javascript
JS实现快递单打印功能【推荐】
2018/06/21 Javascript
让webpack+vue-cil项目不再自动打开浏览器的方法
2018/09/27 Javascript
jQuery实现购物车的总价计算和总价传值功能
2018/11/28 jQuery
微信小程序如何调用新闻接口实现列表循环
2019/07/02 Javascript
使用pkg打包ThinkJS项目的方法步骤
2019/12/30 Javascript
node运行js获得输出的三种方式示例详解
2020/07/02 Javascript
Python ljust rjust center输出
2008/09/06 Python
Python实现的生成自我描述脚本分享(很有意思的程序)
2014/07/18 Python
Python实现Sqlite将字段当做索引进行查询的方法
2016/07/21 Python
正确理解python中的关键字“with”与上下文管理器
2017/04/21 Python
python十进制和二进制的转换方法(含浮点数)
2018/07/07 Python
在python中按照特定顺序访问字典的方法详解
2018/12/14 Python
Python判断变量名是否合法的方法示例
2019/01/28 Python
python批量修改文件夹及其子文件夹下的文件内容
2019/03/15 Python
Python的matplotlib绘图如何修改背景颜色的实现
2019/07/16 Python
Pycharm+Python工程,引用子模块的实现
2020/03/09 Python
Python3标准库之threading进程中管理并发操作方法
2020/03/30 Python
Python Opencv中用compareHist函数进行直方图比较对比图片
2020/04/07 Python
Python gevent协程切换实现详解
2020/09/14 Python
汽车技术服务与营销专业推荐信
2013/11/29 职场文书
生物科学专业自荐书
2014/06/20 职场文书
社会实践活动总结范文
2014/07/03 职场文书
公司租房协议书
2014/10/14 职场文书
《孙子兵法》:欲成大事者,需读懂这些致胜策略
2019/08/23 职场文书
python实现监听键盘
2021/04/26 Python