php实现简易json rpc框架

AndyYang| 阅读:237 发表时间:2017-06-22 14:54:03 php
摘要:RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。

RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。

RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。

一、PHP服务端
server.php文件源码:

<?php
// member 为测试类(可拆开)
class member{
    public function getName($name){
        return 'please click '.$name ;  // 返回字符串
    }
}

class jsonRPCServer {
    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 ('result'=> $result, 'error'=> NULL);
            } else {
                $response = array ('result'=> NULL, 'error' => 'unknown method or incorrect parameters');
            }
        } catch (Exception $e) {
            $response = array ('result' => NULL, 'error' =>$e->getMessage());
        }
        
        header('content-type: text/javascript');
        echo json_encode($response);
        return true;
    }
}

// 注入实例
$myExample = new member();
jsonRPCServer::handle($myExample) or print 'no request'; 

二、PHP客户端
jsonRPCClient.php 文件源码:

<?php
/*
 * more:webyang.net
 */
class jsonRPCClient {
    private $debug;
    private $url;

    /**
     * @param $url
     * @param bool $debug
     */
    public function __construct($url,$debug = false) {
        $this->url = $url;
        empty($debug) ? $this->debug = false : $this->debug = 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');
        }

        // 拼装成一个request请求
        $request = array('method' => $method, 'params' => $params);
        $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));
        }

        if (!is_null($response['error'])) {
            throw new Exception('Request error: '.$response['error']);
        }

        return $response['result'];
    }
}

client.php 文件源码:

<?php
require_once 'jsonRPCClient.php';

//服务端地址
$url = 'http://webyang.net/server.php';
$myExample = new jsonRPCClient($url);

// 客户端调用
try {
    $name = $myExample->getName("<a target='_blank' href='http://webyang.net'>webyang.net</a>");
    echo $name ;
} catch (Exception $e) {
    echo nl2br($e->getMessage()).'<br />'."\n";
}

访问client.php,调用服务端的方法。

本文为AndyYang原创,转载请注明出处!
如果您觉得好,可以打赏作者:

已有1条评论

昵称:
邮箱:

  • 最新评论

phper2017-06-25 13:23:38
这个有点类似webservices.
若兰网 - www.rolan.wang
反馈
微信订阅号