dan-da / json-rpc
简单的Json-RPC客户端/服务器库,只需使用即可
Requires
- php: >=5.4
Requires (Dev)
- phpunit/phpunit: 4.8.*
This package is auto-updated.
Last update: 2024-08-28 04:47:27 UTC
README
一个简单且只需使用即可工作的Json-RPC客户端/服务器。
基于最新更改的fguillot/JsonRPC的完整分支。
功能
- 仅支持JSON-RPC 2.0
- 服务器支持批量请求和通知
- 基于IP的客户端限制和认证
- 自定义中间件
- 完全单元测试
- 要求:PHP >= 5.4
- 许可证:MIT
此版本由dan-da分支,支持为调试目的记录原始HTTP请求/响应,并可选择返回未解析的JSON响应给调用者。
作者
Frédéric Guillot
(此分支版本由dan-da修改)
使用Composer安装
对于PHP >= 5.4
composer require dan-da/json-rpc
运行测试用例 -- 可选
- git clone https://github.com/matasarei/JsonRPC.git
- cd JsonRPC
- composer install
- 运行vendor/bin/phpunit,例如
$ vendor/bin/phpunit
PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
................................................................. 65 / 94 ( 69%)
.............................
Time: 81 ms, Memory: 6.00MB
OK (94 tests, 127 assertions)
`
示例
服务器
回调绑定
<?php use JsonRPC\Server; $server = new Server(); $server->getProcedureHandler() ->withCallback('addition', function ($a, $b) { return $a + $b; }) ->withCallback('random', function ($start, $end) { return mt_rand($start, $end); }) ; echo $server->execute();
从数组中进行回调绑定
<?php use JsonRPC\Server; $callbacks = array( 'getA' => function() { return 'A'; }, 'getB' => function() { return 'B'; }, 'getC' => function() { return 'C'; } ); $server = new Server(); $server->getProcedureHandler()->withCallbackArray($callbacks); echo $server->execute();
类/方法绑定
<?php use JsonRPC\Server; class Api { public function doSomething($arg1, $arg2 = 3) { return $arg1 + $arg2; } } $server = new Server(); $procedureHandler = $server->getProcedureHandler(); // Bind the method Api::doSomething() to the procedure myProcedure $procedureHandler->withClassAndMethod('myProcedure', 'Api', 'doSomething'); // Use a class instance instead of the class name $procedureHandler->withClassAndMethod('mySecondProcedure', new Api, 'doSomething'); // The procedure and the method are the same $procedureHandler->withClassAndMethod('doSomething', 'Api'); // Attach the class, the client will be able to call directly Api::doSomething() $procedureHandler->withObject(new Api()); echo $server->execute();
从数组中进行类/方法绑定
<?php use JsonRPC\Server; class MathApi { public function addition($arg1, $arg2) { return $arg1 + $arg2; } public function subtraction($arg1, $arg2) { return $arg1 - $arg2; } public function multiplication($arg1, $arg2) { return $arg1 * $arg2; } public function division($arg1, $arg2) { return $arg1 / $arg2; } } $callbacks = array( 'addition' => array( 'MathApi', addition ), 'subtraction' => array( 'MathApi', subtraction ), 'multiplication' => array( 'MathApi', multiplication ), 'division' => array( 'MathApi', division ) ); $server = new Server(); $server->getProcedureHandler()->withClassAndMethodArray($callbacks); echo $server->execute();
服务器中间件
中间件可以用来认证和授权客户端。它们在每次过程之前执行。
<?php use JsonRPC\Server; use JsonRPC\MiddlewareInterface; use JsonRPC\Exception\AuthenticationFailureException; class Api { public function doSomething($arg1, $arg2 = 3) { return $arg1 + $arg2; } } class MyMiddleware implements MiddlewareInterface { public function execute($username, $password, $procedureName) { if ($username !== 'foobar') { throw new AuthenticationFailureException('Wrong credentials!'); } } } $server = new Server(); $server->getMiddlewareHandler()->withMiddleware(new MyMiddleware()); $server->getProcedureHandler()->withObject(new Api()); echo $server->execute();
当API凭证错误时,可以抛出AuthenticationFailureException
,当用户不允许访问过程时,可以抛出AccessDeniedException
。
客户端
具有位置参数的示例
<?php use JsonRPC\Client; $client = new Client('http://localhost/server.php'); $result = $client->execute('addition', [3, 5]);
具有命名参数的示例
<?php use JsonRPC\Client; $client = new Client('http://localhost/server.php'); $result = $client->execute('random', ['end' => 10, 'start' => 1]);
参数按照正确的顺序调用。
使用魔术方法__call()
的示例
<?php use JsonRPC\Client; $client = new Client('http://localhost/server.php'); $result = $client->random(50, 100);
上面的示例使用位置参数进行请求,而此示例使用命名参数。
$result = $client->random(['end' => 10, 'start' => 1]);
客户端批量请求
在一个HTTP请求中调用多个过程
<?php use JsonRPC\Client; $client = new Client('http://localhost/server.php'); $results = $client->batch() ->foo(['arg1' => 'bar']) ->random(1, 100) ->add(4, 3) ->execute('add', [2, 5]) ->send(); print_r($results);
所有结果都存储在调用的同一位置。
客户端异常
客户端异常通常在服务器返回错误时抛出。您可以通过使用$returnException
参数来更改此行为,这会导致返回异常。这在执行批量请求时非常有用。
BadFunctionCallException
:服务器上找不到过程InvalidArgumentException
:过程参数错误JsonRPC\Exception\AccessDeniedException
:拒绝访问JsonRPC\Exception\ConnectionFailureException
:连接失败JsonRPC\Exception\ServerErrorException
:内部服务器错误
启用客户端调试
您可以通过启用调试模式来查看JSON请求和响应
<?php use JsonRPC\Client; $client = new Client('http://localhost/server.php'); $client->getHttpClient()->withDebug();
调试输出发送到PHP系统日志。您可以在php.ini
中配置日志目标。
输出示例
==> Request: { "jsonrpc": "2.0", "method": "removeCategory", "id": 486782327, "params": [ 1 ] } ==> Response: { "jsonrpc": "2.0", "id": 486782327, "result": true }
基于IP的客户端限制
服务器只能允许某些IP地址
<?php use JsonRPC\Server; $server = new Server; // IP client restrictions $server->allowHosts(['192.168.0.1', '127.0.0.1']); [...] // Return the response to the client echo $server->execute();
如果客户端被阻止,您会收到403禁止的HTTP响应。
HTTP基本认证
如果您使用HTTPS,可以使用用户名/密码允许客户端。
<?php use JsonRPC\Server; $server = new Server; // List of users to allow $server->authentication(['user1' => 'password1', 'user2' => 'password2']); [...] // Return the response to the client echo $server->execute();
在客户端,设置凭证如下
<?php use JsonRPC\Client; $client = new Client('http://localhost/server.php'); $client->getHttpClient() ->withUsername('Foo') ->withPassword('Bar');
如果认证失败,客户端将抛出RuntimeException。
使用替代认证头
use JsonRPC\Server; $server = new Server(); $server->setAuthenticationHeader('X-Authentication'); $server->authentication(['myusername' => 'mypassword']);
上面的示例将使用HTTP头X-Authentication
而不是标准的Authorization: Basic [BASE64_CREDENTIALS]
。用户名/密码值需要以base64编码:base64_encode('username:password')
。
本地异常
默认情况下,服务器将所有异常转发给客户端。如果您只想转发部分异常,请使用方法Server::withLocalException($exception)
。
<?php use JsonRPC\Server; class MyException1 extends Exception {}; class MyException2 extends Exception {}; $server = new Server(); // Exceptions that should NOT be relayed to the client, if they occurs $server ->withLocalException('MyException1') ->withLocalException('MyException2') ; [...] echo $server->execute();
客户端请求前的回调
您可以使用回调在向服务器发送请求之前更改HTTP头或URL。
示例
<?php $client = new Client(); $client->getHttpClient()->withBeforeRequestCallback(function(HttpClient $client, $payload) { $client->withHeaders(array('Content-Length: '.strlen($payload))); }); $client->myProcedure(123);