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中使用反射技术的架构插件使用说明
May 18 PHP
Php获取金书网的书名的实现代码
Jun 11 PHP
php 操作符与控制结构
Mar 07 PHP
基于MySQL体系结构的分析
May 02 PHP
深入PHP数据缓存的使用说明
May 10 PHP
jQuery向下滚动即时加载内容实现的瀑布流效果
Jan 07 PHP
php编程中echo用逗号和用点号连接的区别
Mar 26 PHP
php微信浏览器分享设置以及回调详解
Aug 01 PHP
thinkPHP显示不出验证码的原因与解决方法分析
May 20 PHP
PHP截取发动短信内容的方法
Jul 04 PHP
laravel 如何实现引入自己的函数或类库
Oct 15 PHP
PHP基于openssl实现非对称加密代码实例
Jun 19 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 日志缩略名的创建函数代码
2010/05/26 PHP
用PHP解决的一个栈的面试题
2014/07/02 PHP
php 利用array_slice函数获取随机数组或前几条数据
2015/09/30 PHP
WordPress开发中的get_post_custom()函数使用解析
2016/01/04 PHP
PHP页面间传递值和保持值的方法
2016/08/24 PHP
PHP页面静态化――纯静态与伪静态用法详解
2020/06/05 PHP
让广告代码不再影响你的网页加载速度
2006/07/07 Javascript
javascript options属性集合操作代码
2009/12/28 Javascript
基于jQuery的树控件实现代码(asp.net+json)
2010/07/11 Javascript
浅析js设置控件的readonly与enabled属性问题
2013/12/25 Javascript
javascript控制图片播放的实现代码
2020/07/29 Javascript
一种Javascript解释ajax返回的json的好方法(推荐)
2016/06/02 Javascript
js实现图片淡入淡出切换简易效果
2016/08/22 Javascript
javascript简写常用的12个技巧(可以大大减少你的js代码量)
2020/03/28 Javascript
Vue2.0实现调用摄像头进行拍照功能 exif.js实现图片上传功能
2018/04/28 Javascript
angularJs中ng-model-options设置数据同步的方法
2018/09/30 Javascript
使用Object.defineProperty如何巧妙找到修改某个变量的准确代码位置
2018/11/02 Javascript
Element Collapse 折叠面板的使用方法
2020/07/26 Javascript
[01:20]PWL S2开团时刻第三期——团战可以输 蝙蝠必须死
2020/11/26 DOTA
[01:06:30]DOTA2-DPC中国联赛定级赛 Phoenix vs DLG BO3第二场 1月9日
2021/03/11 DOTA
Python多线程和队列操作实例
2015/06/21 Python
Python探索之URL Dispatcher实例详解
2017/10/28 Python
django 按时间范围查询数据库实例代码
2018/02/11 Python
python爬取网页内容转换为PDF文件
2020/07/28 Python
Python 使用 Pillow 模块给图片添加文字水印的方法
2019/08/30 Python
CSS3中animation实现流光按钮效果
2020/12/21 HTML / CSS
Html5 postMessage实现跨域消息传递
2016/03/11 HTML / CSS
美国彩妆品牌:Coastal Scents
2017/04/01 全球购物
DC Shoes官网:美国滑板鞋和服饰品牌
2017/09/03 全球购物
Fossil美国官网:化石手表、手袋、首饰及配饰
2019/02/17 全球购物
DC Shoes荷兰官方网站:美国极限运动品牌
2019/10/22 全球购物
WEB控件及HTML服务端控件能否调用客户端方法?如果能,请解释如何调用?
2015/08/25 面试题
工商管理毕业生推荐信
2013/12/24 职场文书
情侣吵架检讨书
2014/02/05 职场文书
公司晚会策划方案
2014/05/17 职场文书
学校献爱心活动总结
2014/07/08 职场文书