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 相关文章推荐
php环境配置 php5 mysql5 apache2 phpmyadmin安装与配置
Nov 17 PHP
PHP生成UTF8文件的方法
May 15 PHP
PHP中对用户身份认证实现两种方法
Jun 04 PHP
利用php获取服务器时间的实现代码
Jun 07 PHP
php生成N个不重复的随机数实例
Nov 12 PHP
thinkphp3查询mssql数据库乱码解决方法分享
Feb 11 PHP
php面象对象数据库操作类实例
Dec 02 PHP
PHP curl CURLOPT_RETURNTRANSFER参数的作用使用实例
Feb 07 PHP
yii2简单使用less代替css示例
Mar 10 PHP
THINKPHP在添加数据的时候获取主键id的值方法
Apr 03 PHP
PHP实现的策略模式简单示例
Aug 25 PHP
php判断目录存在的简单方法
Sep 26 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
收音机指标测试方法及仪器
2021/03/01 无线电
swfupload 多文件上传实现代码
2008/08/27 PHP
destoon供应信息title调用出公司名称的方法
2014/08/22 PHP
Laravel框架使用Redis的方法详解
2018/05/30 PHP
tp5框架前台无限极导航菜单类实现方法分析
2020/03/29 PHP
tp5.1 框架数据库-数据集操作实例分析
2020/05/26 PHP
Javascript自定义函数判断网站访问类型是PC还是移动终端
2014/01/10 Javascript
jquery插件开发之实现jquery手风琴功能分享
2014/03/10 Javascript
禁用页面部分JavaScript不是全部而是部分
2014/09/03 Javascript
jquery事件preventDefault()方法用法实例
2015/01/16 Javascript
js实现头像图片切割缩放及无刷新上传图片的方法
2015/07/17 Javascript
IE中document.createElement的iframe无法设置属性name的解决方法
2015/09/14 Javascript
vue.js表格组件开发的实例详解
2016/10/12 Javascript
简单理解js的prototype属性及使用
2016/12/07 Javascript
微信小程序 自己制作小组件实例详解
2016/12/22 Javascript
bootstrap导航条实现代码
2016/12/28 Javascript
JS使用贪心算法解决找零问题示例
2017/11/27 Javascript
vue项目常用组件和框架结构介绍
2017/12/24 Javascript
微信小程序canvas实现刮刮乐效果
2018/07/09 Javascript
react 应用多入口配置及实践总结
2018/10/17 Javascript
python双向链表实现实例代码
2013/11/21 Python
Python实现Pig Latin小游戏实例代码
2018/02/02 Python
python3 kmp 字符串匹配的方法
2018/07/07 Python
Flask框架各种常见装饰器示例
2018/07/17 Python
python中正则表达式 re.findall 用法
2018/10/23 Python
Python推导式简单示例【列表推导式、字典推导式与集合推导式】
2018/12/04 Python
python识别验证码图片实例详解
2020/02/17 Python
python实现图片横向和纵向拼接
2020/03/05 Python
浅谈python3 构造函数和析构函数
2020/03/12 Python
python怎么调用自己的函数
2020/07/01 Python
Python环境配置实现pip加速过程解析
2020/11/27 Python
澳大利亚婴儿喂养品牌:Cherub Baby
2018/11/01 全球购物
网络宣传方案
2014/03/15 职场文书
宝宝满月酒主持词和仪式流程
2014/03/27 职场文书
写给同学的新学期寄语
2015/02/27 职场文书
个人自荐书怎么写
2015/03/26 职场文书