文件补齐

This commit is contained in:
候学杰 2019-01-05 11:25:30 +08:00
parent ff68778d4b
commit b9361f6cab
7 changed files with 1328 additions and 3 deletions

View File

@ -3,11 +3,13 @@
"type": "library",
"description": "json rpc server/client.",
"require": {
"guzzlehttp/guzzle": "^6.3"
"guzzlehttp/guzzle": "^6.3",
"illuminate/support": "^5.7",
"illuminate/http": "^5.7"
},
"autoload": {
"psr-4": {
"JsonRpc\\": "src/"
}
}
}
}

1092
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,49 @@
<?php
namespace JsonRpc\Providers;
use Illuminate\Support\ServiceProvider;
use JsonRpc\Server\JsonRpcServer;
use Laravel\Lumen\Application;
class LumenServerServiceProvider extends ServiceProvider
{
/**
* @var Application
*/
protected $app;
/**
* @var JsonRpcServer
*/
protected $server;
public function boot()
{
$this->app->router->group([
// 'middleware' => 'rpc',
], function () {
$callback = function () {
$server = new JsonRpcServer();
return $server->handler();
};
$this->app->router->post('rpc/gateway.json', $callback);
$this->app->router->get('rpc/gateway.json', $callback);
$this->app->router->get('rpc/doc.html', function () {
$doc = new JsonRpcDoc(base_path('app/Rpc/'));
return $doc->render();
});
});
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
}
}

View File

@ -0,0 +1,37 @@
<?php
namespace JsonRpc\Server;
class JsonRpcMethod
{
protected $id;
protected $request;
final public function __construct($id, $request)
{
$this->id = $id;
$this->request = $request;
}
public function response($result)
{
return JsonResponse::create([
'jsonrpc' => '2.0',
'result' => $result,
'id' => $this->id
]);
}
public function error($code, $msg)
{
return JsonResponse::create([
'jsonrpc' => '2.0',
'error' => [
'code' => $code,
'message' => $msg,
],
'id' => $this->id
]);
}
}

View File

@ -0,0 +1,122 @@
<?php
namespace JsonRpc\Server;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class JsonRpcServer
{
const Rpc_Error_Parse_Error = -32700;
const Rpc_Error_Invalid_Request = -32600;
const Rpc_Error_NOT_FOUND = -32601;
const Rpc_Error_Invalid_Params = -32602;
const Rpc_Error_Internal_Error = -32603;
const ErrorMsg = [
self::Rpc_Error_NOT_FOUND => 'Method not found',
self::Rpc_Error_Parse_Error => 'Json parse error',
self::Rpc_Error_Invalid_Request => 'Invalid request',
self::Rpc_Error_Invalid_Params => 'Invalid params',
];
/**
* @var Request
*/
public $request;
public function __construct($config)
{
$this->request = function_exists('app') ? app('request') : Request::capture();
}
public function handler()
{
if ($this->request->getContentType() != 'json') {
return $this->error(self::Rpc_Error_Invalid_Request);
}
try {
list($method, $params, $id) = $this->parseJson($this->request->getContent());
list($class, $function) = $this->parseMethod($method);
if (!class_exists($class) || !method_exists($class, $function)) {
return $this->error(self::Rpc_Error_NOT_FOUND);
}
if (!$this->isEnoughParameter($class, $function, $params)) {
return $this->error(self::Rpc_Error_Invalid_Params);
}
$ret = call_user_func_array([(new $class($id, $this->request)), $function], $params);
return $ret;
} catch (\InvalidArgumentException $e) {
return $this->error(self::Rpc_Error_Parse_Error);
}
}
protected function parseJson($data)
{
$data = \GuzzleHttp\json_decode($data, true);
$method = $data['method'];
$params = $data['params'];
$id = $data['id'];
return [$method, $params, $id];
}
protected function parseMethod($method)
{
$method = explode('.', $method);
if (count($method) < 2) {
return ['', ''];
}
$function = array_pop($method);
$class = 'Rpc' . ucwords(array_pop($method));
foreach ($method as $one) {
$class = ucwords($one) . '\\' . $class;
}
$class = "App\Rpc\\$class";
return [$class, $function];
}
protected function isEnoughParameter($class, $method, $parameters)
{
$r = new \ReflectionMethod($class, $method);
$params = $r->getParameters();
$n = 0;
foreach ($params as $param) {
//$param is an instance of ReflectionParameter
if (!$param->isOptional()) {
$n++;
}
}
return count($parameters) >= $n;
}
protected function error($code, $msg = null, $id = null)
{
if ($msg === null) {
$msg = isset(self::ErrorMsg[$code]) ? self::ErrorMsg[$code] : 'undefined';
}
return JsonResponse::create([
'jsonrpc' => '2.0',
'error' => [
'code' => $code,
'message' => $msg,
],
'id' => $id
]);
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace JsonRpc\Server;
class JsonRpcDoc
{
protected $methods = [];
public function __construct($dir)
{
$this->methods = include $dir . '/methods.php';
}
public function methods()
{
return $this->methods;
}
public function render()
{
return view('doc', ['doc' => $this]);
}
}