实现接入tp6 think-金年会app官方网

公司多个项目之前用的tp3.2,去年部份项目升级为tp6,并使用了jsonrpc服务,使用了tp6官方插件 think-swoole中rpc服务,实现了rpc客户端和服务端,但从便携性上讲,需要项目都是tp6才能快速接入rpc服务。
之前部份老项目由于升级成本过大,迟迟没有升级到tp6。由于某些模块需要在新老项目中都需要用到,所以会容易造成新老项目中相同模块中的代码逻辑不一致的问题。
为了解决这个问题,去看了下think-swoole中关于rpc服务的代码,按照里面的逻辑,仿照写了一个调用rpc服务的客户端类。
代码如下:


$orderrpc = new corerpc('order');
$data = [
    'servicetype' => 0,
];
$res = $orderrpc->estimate($data);
var_dump($res);
class corerpc
{
    protected $host = '127.0.0.1';  //rpc服务ip
    protected $port = 10001; //rpc服务端口
    protected $timeout = 5;
    protected $client;
    protected $interface;
    protected $rpcfunc = [
        'orderrpcinterface' => ['estimate', 'order'],
        'userrpcinterface' => ['create'],
    ];
    protected $interfaces = [
        'order' => 'orderrpcinterface',
        'user' => 'userrpcinterface',
    ];
    public function __construct($interface)
    {
        $this->interface = $interface;
    }
    protected function isconnected(): bool
    {
        return $this->client && $this->client->isconnected();
    }
    protected function getclient()
    {
        if (!$this->isconnected()) {
            $client = new swoole\client(swoole_sock_tcp);
            if (!$client->connect($this->host, $this->port, $this->timeout)) {
            throw new exception(sprintf('connect failed host=%s port=%d', $this->host, $this->port));
                }
            $this->client = $client;
        }
        return $this->client;
    }
    public function packdata($interface, $func, $arguments)
    {
        $method = $interface . '@' . $func;
        $data = [
            'jsonrpc' => '2.0',
            'method'  => $method,
            'params'  => $arguments,
            'context' => [],
            'id'      => '',
        ];
        $json = json_encode($data, json_unescaped_unicode);
        return pack('nn', strlen($json), 0) . $json;
    }
    public function __call($method, array $arguments)
    {
        $interface = $this->interface;
        if(!isset($this->interfaces[$interface])){
            throw new exception('非法的interface');
        }
        $rpcfunc = $this->rpcfunc[$this->interfaces[$interface]];
        if(!in_array($method, $rpcfunc)){
            throw new exception('非法的method');
        }
        $pack = $this->packdata($this->interfaces[$interface], $method, $arguments);
        return $this->sendandrecv($pack);
    }
    protected function sendandrecv($data)
    {
        return $this->runwithclient(function (swoole\client $client) use ($data) {
            try {
                if ($client->send($data) === false) {
                    throw new exception('send data failed.');
                }
                $response = $client->recv();
                // 处理响应数据
                if ($response === false) {
                    throw new exception('recv data failed.');
                }
                $res = substr($response,8);
                $data = json_decode($res, true);
                return $data['result'];
            } catch (exception $e) {
                $client->close();
                throw $e;
            }
        });
    }
    protected function runwithclient($callback)
    {
        return $callback($this->getclient());
    }
}

效果如下:

实现接入tp6 think-swoole rpc服务
完美。
老项目也可以愉快的接进来了

本作品采用《cc 协议》,转载必须注明作者和本文链接
to live is to change the world
本帖由系统于 1年前 自动加精
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
网站地图