实现接入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());
}
}
效果如下:
完美。
老项目也可以愉快的接进来了
本作品采用《cc 协议》,转载必须注明作者和本文链接
to live is to change the world
本帖由系统于 1年前 自动加精