PHP 使用 hprose RPC 服务 系列文章之一——安装扩展
PHP 使用 hprose RPC 服务 系列文章之二——Codeigniter3中使用Hprose
PHP 使用 hprose RPC 服务 系列文章之三——Laravel5.8中使用Hprose
引入hprose
这里使用hprose/hprose,不使用github上大神们封装的laravel-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
添加路由
- 服务端路由
//服务端 $route->match(['get', 'post'], 'hprose/server', 'HproseController@server')->name('api_v1_hprose_server');
- 客户端路由
//客户端 $route->match(['get', 'post'], 'hprose/client_test', 'HproseController@client_test')->name('api_v1_hprose_client_test');
创建HproseTrait
该文件是启动hprose服务和进行客户端请求的操作,是对controller的扩展。
-
HproseTrait
<?php namespace App\Libraries\HttpRequest; use Hprose\Http\Client; use Hprose\Http\Server; trait HproseTrait { /** * 启动服务 */ public function server() { $params = request()->all(); $method = $params['method']; $server = new Server(); $at_flag = request()->hasHeader('access_token'); if ($at_flag) { $server->header('access_token', request()->header('access_token'), ''); } $server->addMethod($method, $this); $server->start(); } /** * 客户端请求 * @return Client $client */ public function client() { $params = request()->all(); $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 = request()->hasHeader('access_token'); if ($at_flag) { $client->setHeader('access_token', request()->header('access_token')); } return $client; } }
在控制器中把HproseTrait类use进来,效果如下:
由于启动服务需要在对应的控制器中,该trait类可以作为公共方法为控制器提供启动服务和客户端请求的调用方法(可能需要优化,有更好建议的小伙伴可以评论里发出来)。一般情况下RPC客户端和服务端不在同一个项目里,server和client分别写在服务端项目和客户端项目里,这里都写在一个项目里了,便于调试,读者在实际使用中需留意。
控制器
- 创建控制器文件,并添加相应方法:
<?php namespace App\Http\Controllers\Api\V1; use Illuminate\Http\Request; use App\Http\Controllers\Controller; class HproseController extends Controller { public function hello($name) { return 'Hello ' . $name; } public function test($name) { return '你好,'.$name; } //请求test方法 public function client_test() { $client = $this->client(); $params = request()->all(); return $client->test($params['data']); } //请求hello方法 public function client_hello() { $client = $this->client(); $params = request()->all(); return $client->hello($params['data']); } }
测试用例
在postman中测试。
-
启动服务
GET方式访问路由http://hammer.me/api/v1/hprose/server?method=test
得到如下结果说明调用的方法服务启动:
test即为控制器中的test方法。 -
进行请求
POST方式访问http://hammer.me/api/v1/hprose/client_test
进行客户端请求,返回如下效果,即为客户端请求成功:
server_url:即为启动服务的地址,只是这里通过传参方式,此url必须和要远程调用的方法路由一致,除了最后的server方法,因为启动server就是注册远程调用的方法(如test、hello);
is_sync:是否异步(0:否,1:是),此处值必传0;
data:参数,具体项目开发过程中客户端要请求某个方法,一般都需要传参,以进行增删改查之类的操作,这里data对应的值就是需要远程调用方法的参数,具体格式可以自行调整。
项目实战
项目使用过程中,一般返回的格式是json,对于返回的结果需要进行json_encode之后在进行json_decode获取最终想要的数据。
例如:
我这里方法projectExtList返回的是json格式:
所以要做上述处理,如果直接返回你需要的数据,就不需要做上述处理。
总结
以上的测试都是通过postman模拟浏览器进行的请求,实际项目中使用时在客户端项目中直接调用远程方法的,省去了浏览器传参及服务器收参的问题,读者在使用上述代码时应注意在自己项目中的调整。