PHP 使用 hprose RPC 服务 系列文章之一——安装扩展
PHP 使用 hprose RPC 服务 系列文章之二——Codeigniter3中使用Hprose
PHP 使用 hprose RPC 服务 系列文章之三——Laravel5.8中使用Hprose
引入hprose
这里使用 hprose/hprose。
hprose github地址
hprose github文档
- composer.json添加hprose包
要安装最新版的话需要将 * 替换为 dev-master"require": { "hprose/hprose": "*" },
添加后在项目根目录执行composer update
即可。 - composer 下载hprose包
执行如下命令:
本文选用v2.0.40版本hprose。composer require hprose/hprose
关于路由
CI3框架可以设定路由,也可以不设置,由于我项目中直接根据目录进行访问作为路由,此处就不设定路由了,读者如使用可路由,依照路由访问也没问题。
添加server和client方法
如果你的CI3项目扩展了命名空间,那么你也可以使用HproseTrait类的方式扩展控制器类(参考第三篇文章 Laravel+Hprose),这样更加合理。如果没有命名空间的概念,那么写一个Hprose_lib类库放在 application/libraries 目录下,添加server和client方法,如下:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
use Hprose\Http\Client;
use Hprose\Http\Server;
class Hprose_lib
{
private $CI;
public function __construct()
{
$this->CI = &get_instance();
}
/**
* 启动服务
*/
public function server()
{
$params = $this->CI->_params;
$params = $params ?: $this->CI->input->get();
$method = $params['method'];
$server = new Server();
$at_flag = $this->CI->input->server('access_token');
if ($at_flag) {
$server->header('access_token', $at_flag, '');
}
$server->addMethod($method, $this->CI);
$server->start();
}
/**
* 客户端请求
* @return Client $client
*/
public function client()
{
$params = $this->CI->_params;
$server_url = $params['server_url'];
$is_sync = $params['is_sync'];
$data = json_decode($params['data'], true);
if ($is_sync) {
$client = new Client($server_url, true);
} else {
$client = new Client($server_url, false);
}
$at_flag = $this->CI->input->server('access_token');
if ($at_flag) {
$client->setHeader('access_token', $at_flag);
}
return $client;
}
}
在公共控制器PS_Controller(自定义PS_前缀,默认是MY_前缀)添加启动服务的方法,这样在任何子级控制器都可以随意调用server方法进行启动server服务:
如上,手动加载Hprose_lib库文件,也可以自动加载。
一般情况下RPC客户端和服务端不在同一个项目里,server和client分别写在服务端项目和客户端项目里,这里都写在一个项目里了,便于调试,读者在实际使用中需留意。
控制器
- 创建控制器文件,并添加相应方法:
<?php defined('BASEPATH') OR exit('No direct script access allowed'); class Hprose extends PS_Controller { public function __construct() { parent::__construct(); } public function test(int $is_ret = 0, array $ct_data = []) { $params = $this->_params; if (empty($params)) { $data = $ct_data; } else if (!empty($params) && array_key_exists('data', $params)) { $data = json_decode($params['data'], true); } else { $data = $params; } $res = "你好,{$data['name']}"; $end = ['info' => $res]; if ($is_ret) { return $end; } else { output_data($end); } } public function client_test() { $client = $this->hprose_lib->client(); $params = $this->_params; $data = json_decode($params['data'], true); $res = $client->test(1, $data); output_data($res); } public function rpc_get_system_tree() { $client = $this->hprose_lib->client(); $res = $client->get_system_tree(1); output_data($res); } }
测试用例
在postman中测试。
-
启动服务
GET方式访问路由http://域名/hprose/v1/hprose/server?method=test
得到如下结果说明调用的方法服务启动:
test即为控制器中的test方法。 -
进行请求
POST方式访问http://域名/hprose/v1/hprose/client_test
进行客户端请求,返回如下效果,即为客户端请求成功(本地http调用可能出现超时,如遇到,不要慌,通过公网服务器访问即可):
server_url:即为启动服务的地址,只是这里通过传参方式,此url必须和要远程调用的方法路由一致,除了最后的server方法,因为启动server就是注册远程调用的方法(如test、hello);
is_sync:是否异步(0:否,1:是),此处值必传0;
data:参数,具体项目开发过程中客户端要请求某个方法,一般都需要传参,以进行增删改查之类的操作,这里data对应的值就是需要远程调用方法的参数,具体格式可以自行调整。
项目实战
CI3项目使用过程中,可以直接返回查询到的数据,客户端获取结果之后直接返回json格式数据:
如上,客户端调用远程方法get_system_tree,直接返回查询结果的处理方式。
总结
以上的测试都是通过postman模拟浏览器进行的请求,实际项目中使用时在客户端项目中直接调用远程方法的,省去了浏览器传参及服务器收参的问题,读者在使用上述代码时应注意在自己项目中的调整。