php实现的一个简单json rpc框架实例
jsonrpc是一种以json为消息格式的远程调用服务,它是一套允许运行在不同操作系统、不同环境的程序实现基于Internet过程调用的规范和一系列的实现。这种远程过程调用可以使用http作为传输协议,也可以使用其它传输协议,传输的内容是json消息体。
下面我们code一套基于php的rpc框架,此框架中包含rpc的服务端server,和应用端client;
(一)PHP服务端RPCserverjsonRPCServer.php
classjsonRPCServer{ /** *处理一个request类,这个类中绑定了一些请求参数 *@paramobject$object *@returnboolean */ publicstaticfunctionhandle($object){ //判断是否是一个rpcjson请求 if($_SERVER['REQUEST_METHOD']!='POST'||empty($_SERVER['CONTENT_TYPE']) ||$_SERVER['CONTENT_TYPE']!='application/json'){ returnfalse; } //readstheinputdata $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'=>'unknownmethodorincorrectparameters');} }catch(Exception$e){ $response=array('id'=>$request['id'],'result'=>NULL,'error'=>$e->getMessage()); } //json格式输出 if(!empty($request['id'])){//notificationsdon'twantresponse header('content-type:text/javascript'); echojson_encode($response); } returntrue; } }
(二)Rpc客户端,jsonRPCClient.php
<?php /* */ classjsonRPCClient{
private$debug; private$url; //请求id private$id; private$notification=false; /** *@param$url *@parambool$debug */ publicfunction__construct($url,$debug=false){ //serverURL $this->url=$url; //proxy empty($proxy)?$this->proxy='':$this->proxy=$proxy; //debugstate empty($debug)?$this->debug=false:$this->debug=true; //messageid $this->id=1; }
/** * *@paramboolean$notification */ publicfunctionsetRPCNotification($notification){ empty($notification)?$this->notification=false :$this->notification=true; }
/** *@param$method *@param$params *@returnbool *@throwsException */ publicfunction__call($method,$params){ //检验request信息 if(!is_scalar($method)){ thrownewException('Methodnamehasnoscalarvalue'); } if(is_array($params)){ $params=array_values($params); }else{ thrownewException('Paramsmustbegivenasarray'); }
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".'*****EndOfrequest*****'."\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{ thrownewException('Unabletoconnectto'.$this->url); } //输出调试信息 if($this->debug){ echonl2br(($this->debug)); } //检验response信息 if(!$this->notification){ //check if($response['id']!=$currentId){ thrownewException('Incorrectresponseid(requestid:'.$currentId.',responseid:'.$response['id'].')'); } if(!is_null($response['error'])){ thrownewException('Requesterror:'.$response['error']); } return$response['result'];
}else{ returntrue; } } } ?>