<?php
namespace app\Rpc;
/**
* RPC对象调用类
*/
class Factory
{
public $RPC_EOL = "\r\n";
/**
* 构造方法
*/
public function __construct($type)
{
$this->type = $type;
try {
$this->host = config('rpc_host')[$type];
} catch (\Throwable $th) {
throw new \Exception('RPC的'.$type.'地址 配置不存在');
}
$this->fp = stream_socket_client($this->host, $errno, $errstr);
if (!$this->fp) {
throw new \Exception("stream_socket_client fail errno={$errno} errstr={$errstr}");
}
}
/**
* 动态请求RPC对象的方法,远程调用RPC
*
* @param string $action
* @param array $params
* @return void
*/
public function __call($action, $params)
{
// hyperf
// {"jsonrpc":"2.0","method":"\/calculator\/add","params":[10,20],"id":"62b6e12b05614","context":[]}
$req = [
"jsonrpc" => '2.0',
"method" => "/$this->type/$action",
'params' => [10, 21],
'id' => '',
'context' => [],
];
$data = json_encode($req) . $this->RPC_EOL;
fwrite($this->fp, $data);
$result = '';
while (!feof($this->fp)) {
$tmp = stream_socket_recvfrom($this->fp, 1024);
if ($pos = strpos($tmp, $this->RPC_EOL)) {
$result .= substr($tmp, 0, $pos);
break;
} else {
$result .= $tmp;
}
}
$result = json_decode($result);
if(isset($result->error)) {
$error = $result->error;
throw new \Exception("请求:RPC-$this->type::$action \n 错误码:$error->code \n 报错:$error->message");
}
return $result->result;
}
// 请求结束后释放对象
public function __destruct()
{
fclose($this->fp);
echo '销毁RPC对象'.$this->type;
}
}
评论0