goldvoice
6 лет назадТехнический пост: легкий JSON-RPC клиент на PHP
Отвязали все запросы через веб-сокеты и перешли на json-rpc. Запросы теперь легче и быстрее. Как и было обещано, публикуем код легкого клиента на сокетах.
class graphene_jsonrpc_web{
public $endpoint='';
public $debug=false;
public $request_arr=array();
public $result_arr=array();
function graphene_jsonrpc_web($endpoint='',$debug=false){
$this->endpoint=$endpoint;
$this->debug=$debug;
$this->request_arr=array();
$this->result_arr=array();
}
function get_url($url,$ref=false,$post=array()){
$this->last_url=$url;
$method='GET';
if($post){
$method='POST';
}
preg_match('#://(.*)/#iUs',$url,$stock);
preg_match('#://'.$stock[1].'/(.*)$#iUs',$url,$stock2);
$host=$stock[1];
$path=$stock2[1];
$request=$method." /".$path." HTTP/1.1\r\n";
$request.="Host: ".$host."\r\n";
if($ref){
$request.="Referer: ".$ref."\r\n";
}
foreach($this->headers_arr as $k=>$v){
if($v){
$request.=$k.': '.$v."\r\n";
}
}
$request.="Connection: close\r\n";
$request.="Content-Type: application/x-www-form-urlencoded\r\n";
$request.="Content-Length: ".strlen($post)."\r\n\r\n";
$request.=$post;
$request.="\r\n";
$request.="\r\n";
if($this->debug){
$this->request_arr[]=$request;
}
$result='';
$port=80;
if(false!==strpos($url,'https://')){
$port=443;
$host='ssl://'.$host;
}
if($sock=fsockopen($host, $port, $errno, $errstr, 4)){
fwrite($sock,$request,strlen($request));
while(!feof($sock)){
$result.=fread($sock,1024);
}
fclose($sock);
}
if($this->debug){
$this->result_arr[]=$result;
}
return $result;
}
function parse_web_result($fp){
$headers=mb_substr($fp,0,mb_strpos($fp,"\r\n\r\n"));
$clear_r=mb_substr($fp,mb_strpos($fp,"\r\n\r\n")+4);
if(false!==strpos($headers,'Transfer-Encoding: chunked')){$clear_r=clear_chunked($clear_r);}
if(false!==strpos($headers,'Content-Encoding: gzip')){$clear_r=gzdecode($clear_r);}
return array($headers,$clear_r);
}
function build_method($api,$method,$params,$array=false){
$params_arr=array();
foreach($params as $k => $v){
if(!is_int($v)){
$params_arr[]='"'.$v.'"';
}
else{
$params_arr[]=$v;
}
}
$return='{"jsonrpc":"2.0","id":1,"method":"call","params":["'.$api.'","'.$method.'",['.($array?'[':'').implode(',',$params_arr).($array?']':'').']]}';
return $return;
}
function execute_method($api,$method,$params,$array=false){
$jsonrpc_query=$this->build_method($api,$method,$params,$array);
list($header,$result)=$this->parse_web_result($this->get_url($this->endpoint,false,$jsonrpc_query));
$result_arr=json_decode($result,true);
return $result_arr['result'];
}
}
Примеры вызова:
$web=new graphene_jsonrpc_web('https://ws.golos.io/',true);
$result_arr1=$web->execute_method('database_api','get_block',array(1000000),false);
print_r($result_arr1);
$result_arr2=$web->execute_method('database_api','get_ops_in_block',array(6754128,'false'),false);
print_r($result_arr2);
$result_arr3=$web->execute_method('database_api','get_accounts',array('goldvoice'),true);
print_r($result_arr3);
$result_arr4=$web->execute_method('database_api','get_content',array('goldvoice','redis-queue-feed-10-01-2018'),false);
print_r($result_arr4);
PS Да, видим, что идет синхронизация. Терпение, только терпение!