alanbem / josser
PHP的JSON-RPC客户端
Requires
- php: >=7.1.0
- guzzlehttp/guzzle: ^5.0|^6.0
- symfony/serializer: ^2.0|^3.0|^4.0|^5.0
Requires (Dev)
- phpunit/phpunit: ^7.0
README
JSON-RPC是什么?
JSON-RPC是一种无状态的轻量级远程过程调用协议,使用JSON进行编码。它是一个非常简单的协议,只定义了一小部分数据类型和命令。
Josser支持哪个版本的JSON-RPC规范?
Josser支持[JSON-RPC 1.0] (http://json-rpc.org/wiki/specification)和[修订版JSON-RPC 2.0] (http://www.jsonrpc.org/specification)。遗憾的是,由于PHP的限制,Josser只能进行客户端-服务器连接——尽管JSON-RPC 1.0最初被设计为P2P。
值得一提的是,Josser的架构允许您插入自己的JSON-RPC版本或实现现有的半标准化JSON-RPC协议,例如废弃的JSON-RPC 1.1WD。
传输机制
正如规范(1.0和2.0)所声明的那样,JSON-RPC与传输无关。Josser坚持这一点,允许使用http、套接字、tcp/ip或其他您项目需要的内容(比如冰箱上的便签:D)。目前只实现了http传输。
文档
使用方法
调用远程方法相对简单
<?php namespace Josser; use GuzzleHttp\Client; use Josser\Client\Transport\Guzzle6Transport as HttpTransport; // there is also guzzle 5 implementation available use Josser\Protocol\JsonRpc1; $guzzle = new Client(['base_uri' => 'http://user:password@your-service.com/math:8888']); // http client $transport = new HttpTransport($guzzle); // RPC over http $protocol = new JsonRpc1; // lets use JSON-RPC 1.0 $client = new Client($transport, $protocol); // send a request $sum = $client->request('sum', array(5, 4)); var_dump($sum); // int(9)
如果远程方法不返回任何内容,则通知是您所需要的
<?php // instantiate client $client->notify('logout');
错误处理
Josser通过一系列异常来报告错误。
<?php namespace Josser; use Josser\Exception\RpcFaultException; use Josser\Exception\TransportFailureException; use Josser\Exception\RequestResponseMismatchException; use Josser\Exception\InvalidResponseException; use Josser\Exception\InvalidRequestException; // instantiate client try { $client->request('method', array(1, "param2")); } catch (RpcFaultException $e) { echo 'Ups! Remote server sent an error.'; } catch (TransportFailureException $e) { echo 'Josser did not send remote call.'; } catch (RequestResponseMismatchException $e) { echo "Response id does not match request id."; } catch (InvalidResponseException $e) { echo "Response object is invalid due to protocol constraints."; } catch(InvalidRequestException $e) { echo "Request is invalid due to protocol constraints."; }
为了方便,存在一个捕获所有异常的通用异常。
<?php namespace Josser; use Josser\Client; use Josser\Exception\JosserException; // instantiate client try { $client->request('method', array(1, "param2")); } catch (JosserException $e) { echo 'Josser error occurred.'; }
请求对象
当您调用远程过程时,这些调用会内部转换为通用请求对象。
<?php namespace Josser; use Josser\Client; use Josser\Client\Request\Request; use Josser\Client\Request\Notification; // instantiate transport and protocol $client = new Client($transport, $protocol); $client->request('math.divide', array(1, 2)); $client->notify('system.logout'); // code above is equivalent of $request = new Request('math.divide', array(1, 2), 213123); // 213123 is a request identifier $client->call($request); $notification = new Notification('system.logout'); $client->call($notification);
如您所见,您可以直接与这些低级对象一起工作,但这种方法的一个缺点是您必须为每个请求提供自己的id。默认情况下,Client::request()会为您生成这个id。还要记住,Client::call()不会直接返回结果——它返回响应对象。要获取底层结果数据,请使用Response::getResult(),如下所示
<?php namespace Josser; use Josser\Client; use Josser\Client\Request\Request; use Josser\Client\Request\Notification; // instantiate client $request = new Request('math.sum', array(2, 2), 6564653); $response = $client->call($request); var_dump($response->getResult()); // int(4)
请注意,您可以创建自己的、针对项目特定的请求对象。
<?php namespace MyProject\Request; use Josser\Client\Request\Request; class Divide extends Request { public function __construct($divident, $divisor) { $requestId = uniqid(); // random request id parent::__construct('math.divide', array($divident, $divisor), $requestId); } }
关于
要求
PHP >= 5.3
提交错误和功能请求
错误和功能请求在Github上进行跟踪
作者
Alan Gabriel Bem - alan.bem@gmail.com
许可
Josser遵循MIT许可证——有关详细信息,请参阅LICENSE文件