简化版 / jr
JSON-RPC 服务器
Requires
- php: >=5.4
- simplon/border: 0.5.*
README
_ _ _ ___(_)_ __ ___ _ __ | | ___ _ __ (_)_ __ / __| | '_ ` _ \| '_ \| |/ _ \| '_ \ | | '__| \__ \ | | | | | | |_) | | (_) | | | | | | | |___/_|_| |_| |_| .__/|_|\___/|_| |_| _/ |_| |_| |__/
简化版/Jr
一个 JSON-RPC 服务器
当前版本:0.6.5
1. 简介
1.1. 什么是 JSON?
JSON(JavaScript 对象表示法)是一种轻量级的数据交换格式。它易于人类阅读和编写。它易于机器解析和生成。请继续阅读[更多内容]。
1.2. 什么是 RPC?
在计算机科学中,远程过程调用(RPC)是一种进程间通信,允许计算机程序在没有程序员明确编码远程交互细节的情况下,在其他地址空间(通常在共享网络上的另一台计算机上)执行子程序或过程。可以实现这一概念的不同(通常是兼容性差)技术。请继续阅读[更多内容]。
1.3. 规范
JSON-RPC 是一种无状态的、轻量级的远程过程调用(RPC)协议。本规范主要定义了几个数据结构及其处理规则。它是传输无关的,因为可以在同一进程内、通过套接字、通过 HTTP 或在许多不同的消息传递环境中使用这些概念。它使用 JSON(RFC 4627)作为数据格式。请继续阅读[更多内容]。
1.4. 请求/响应示例
客户端请求
{"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3}
服务器响应
{"jsonrpc": "2.0", "result": 19, "id": 3}
2. 示例设置
以下步骤应该演示简化版/Jr 的标准工作示例。示例设置位于测试文件夹中,这是本存储库的一部分。
2.1. 依赖项
简化版/Jr 是基于 PHP 依赖管理器 Composer 构建的。如果您还没有安装 composer,请现在安装。熟悉 Composer 非常重要。因此,请花些时间查看 composer 的文档。
使用您的终端并切换到测试文件夹。输入 ls -la
应该会显示类似于以下的内容
drwxr-xr-x 6 fightbulc staff 204 11 Mär 15:09 .
drwxr-xr-x 12 fightbulc staff 408 11 Mär 11:05 ..
drwxr-xr-x 3 fightbulc staff 102 11 Mär 14:39 client
-rw-r--r-- 1 fightbulc staff 251 11 Mär 12:00 composer.json
drwxr-xr-x 4 fightbulc staff 136 11 Mär 11:39 server
《code>composer.json 文件揭示了某些包详细信息,更重要的是,它告诉 Composer 关于我们的依赖项
{ "name": "simplon/jr_testing", "description": "JSON-RPC Server testing", "require": { "php": ">=5.4", "simplon/jr": "0.5.2", "fightbulc/jsonrpc_curl": "0.5.1" }, "autoload": { "psr-0": { "App": "server/" } } }
好,我们已经说够了。让我们通过 composer install
安装依赖项。这应该在您的屏幕上产生一些动作,进而留下我们的依赖项和 composer 自动加载类的映射(所有这些都位于 vendor 文件夹中)
drwxr-xr-x 8 fightbulc staff 272 11 Mär 15:18 .
drwxr-xr-x 12 fightbulc staff 408 11 Mär 11:05 ..
drwxr-xr-x 3 fightbulc staff 102 11 Mär 14:39 client
-rw-r--r-- 1 fightbulc staff 251 11 Mär 12:00 composer.json
-rw-r--r-- 1 fightbulc staff 5571 11 Mär 15:18 composer.lock
drwxr-xr-x 4 fightbulc staff 136 11 Mär 11:39 server
drwxr-xr-x 6 fightbulc staff 204 11 Mär 15:18 vendor
2.2. 服务器
很好,现在我们应该有了我们的依赖项,让我们开始构建我们的服务器。为了完成这项任务,我们需要执行三个步骤,如果我们要包含身份验证,则需要四个步骤。请按照以下步骤进行
2.2.1. 网关
首先,让我们创建一个 Gateway 类
。网关类定义了服务设置的所有要求。服务是通过给定的域名分开的。在我们的示例中,我们将选择域名 Web
。因此,我们的网关类位于 /server/App/Api/Web/Gateway.php
namespace App\Api\Web; use Simplon\Jr\Interfaces\InterfaceGateway; class Gateway extends \Simplon\Jr\Gateway implements InterfaceGateway { /** * @return bool */ public function isEnabled() { return TRUE; } // ########################################## /** * @return bool|string */ public function getNamespace() { return __NAMESPACE__; } // ########################################## /** * @return bool */ public function hasAuth() { return FALSE; } // ########################################## /** * @return array|bool */ public function getValidServices() { return array( 'Web.Base.hello', 'Web.Base.getUsernameById', ); } }
暂且不提继承和接口实现:我们看到什么?
我们通过 isEnabled()
函数声明服务已启用,只需简单地返回 TRUE
即可。否则,将拒绝任何对服务的请求。另一个有趣的方法是 hasAuth()
。与先前的函数类似,它是通过返回 TRUE || FALSE
来开启或关闭身份验证。现在让我们假设我们没有身份验证,来看看 getValidServices()
方法。此方法返回允许的服务请求数组。每个字符串由一个 API 域
(例如 Web)、一个 服务类名称
(例如 Base)和一个 服务类方法名称
组成。所有部分都由点分隔。
2.2.2. 身份验证
回到上面提到的身份验证。如果 hasAuth()
返回 TRUE
,则服务器期望在网关自身所在的同一目录下有一个身份验证类 /server/App/Api/Web/Auth.php
namespace App\Api\Web; class Auth { public function init($user, $pass) { if($user === 'admin' && $pass == '123456') { return TRUE; } return FALSE; } }
身份验证类至少需要一个名为 init()
的方法。它可以包含任意数量的参数,只要它们是请求参数的一部分。在此方法中可以运行任何类型的验证。服务器期望返回 TRUE
以授权访问,返回 FALSE
以表示身份验证失败。
2.2.3. 服务类
如果网关已启用,我们将身份验证(如果有)和传入的服务 API 请求与我们的有效服务列表匹配,则请求将进入请求的服务类。
假设以下请求已发送 Web.Base.hello
,这将到达以下服务类 /server/App/Api/V1/Web/Service/BaseService.php
namespace App\Api\Web\Service; use App\Manager\UserManager; class BaseService { /** * @return string */ public function hello() { return 'Hello!'; } // ########################################## /** * @param $userId * @return string */ public function getUsernameById($userId) { $username = (new UserManager())->getUsername($userId); return $username; } }
服务类标志着我们的 JSON-RPC 服务器结束。现在我们的服务器等待从调用的服务类方法返回响应,以便将其返回给客户端。在我们的例子中,服务器运行 hello()
方法,返回一个字符串。我们的客户端接收 Hello!
作为响应。
所有其他工作,例如对数据库的调用,应在另一个类中处理 - 所说的 Manager 类
。只有结果应返回给服务类,以便它可以返回给客户端。《服务类》应保持 瘦而简单,而《Manager 类》则在幕后 做所有工作和魔法。这应该始终记住,以支持代码的可重用性。
第二个示例展示了描述的技术。服务器接收到一个带有 userId
参数的请求 Web.Base.getUsernameById
。该方法接受参数并将其传递给 UserManager
类以获取 username
。所有这一切如何发生对 Service
类来说并不重要。重要的是用户名。
这里是一个提到的 UserManager
的示例骨架
namespace App\Manager; class UserManager { /** * @param $id * @return string */ public function getUsername($id) { $username = NULL; // do some work and return ... // return $username; // fake return return 'Hansi'; } }
2.2.4. 服务引导
那么还有什么?
为了完成我们的服务器,我们还需要一个引导文件,它用作域服务的单入口点。我们需要的只是一个公开可用的文件,它连接到我们先前创建的服务网关 /server/public/api/web/index.php
require __DIR__ . '/../../../../vendor/autoload.php'; $gtw = new App\Api\Web\Gateway();
这个文件做什么?它加载 composer 的自动加载器,这使得我们可以自动加载我们的网关类。一旦加载了网关,服务器就会读取传入的请求,并开始执行上述处理。
2.3. 客户端
现在服务器已经完成,我们需要一个可以与我们的服务通信的客户端。我编写了一个名为 JSONRPC_CURL 的小类,它使得请求变得非常简单。您已经在开始时安装了它,因为它是我们的测试文件夹包的一部分。
我们的客户端文件可以在这里找到 /client/request_server_testing.php
。
为了与我们的描述示例保持一致,以下代码将调用我们的服务 Web.Base.hello
。请确保 $urlServiceGateway 包含正确的服务器 URL
// url to server gateway $urlServiceGateway = 'http://localhost/opensource/server/simplon/simplon_jr/test/server/public'; // ############################################ // send request $response = (new JsonRpcCurl()) ->setUrl($urlServiceGateway . '/api/web/') // server url ->setId(1) // request ID (important for batch/async) ->setMethod('Web.Base.hello') // requested service ->send(); // send request // dump response var_dump($response); // should print: string(6) "Hello!"
并且既然我们提到了 UserManager
类,这里有一个示例
// url to server gateway $urlServiceGateway = 'http://localhost/opensource/server/simplon/simplon_jr/test/server/public'; // ############################################ // send request $response = (new JsonRpcCurl()) ->setUrl($urlServiceGateway . '/api/web/') ->setId(1) ->setMethod('Web.Base.getUsernameById') ->setData(['id' => 35]) ->send(); // dump response var_dump($response); // prints: Hansi
2.4. 身份验证请求
最后,这里有一个认证请求的示例。请确保在您的网关类中的hasAuth()
函数返回TRUE
。这应该将每个请求通过我们的认证类。
现在让我们向客户端添加必要的用户数据
// url to server gateway $urlServiceGateway = 'http://localhost/opensource/server/simplon/simplon_jr/test/server/public'; // ############################################ // auth data $data = [ 'user' => 'admin', 'pass' => '123456', ]; // send request $response = (new JsonRpcCurl()) ->setUrl($urlServiceGateway . '/api/web/') // server url ->setId(1) // request ID (important for batch/async) ->setMethod('Web.Base.hello') // requested service ->setData($data) // holds auth data ->send(); // send request // dump response var_dump($response); // should print: string(6) "Hello!"
缺少所需的认证数据或传递错误的数据都不会有任何帮助。试试看。
许可证
Cirrus可以在MIT许可证的条款下自由分发。
版权(c)2014 Tino Ehrich (opensource@efides.com)
特此授予任何获得此软件及其相关文档副本(“软件”)的个人免费使用软件的权利,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售软件副本,并允许向软件提供者提供软件的人这样做,前提是遵守以下条件
上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。
软件按“现状”提供,不提供任何明示或暗示的保证,包括但不限于适销性、适用于特定目的和侵权保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任承担责任,无论该责任是基于合同、侵权或其他原因,无论该责任产生于、因之而存在或与此有关,包括但不限于软件或软件的使用或其它处置。