Php rpc 服务端提供计算器服务(加减乘除),Java rpc 客户端通过 thrift api 对其进行调用。改编自thrift官方教程,主要是为了看起来更加简单。
- 编写接口描述文件 calculator.thrift
namespace java app.rpc.learn
namespace php App.Rpc.Learn
enum Operation {
ADD = 1,
SUBTRACT = 2,
MULTIPLY = 3,
DIVIDE = 4
}
exception InvalidOperation {
1: i32 whatOp,
2: string why
}
service Calculator {
double calculate(1:double num1, 2:double num2, 3:Operation op) throws (1:InvalidOperation ouch),
}
- 使用 thrift编译器生成 PHP服务端及Java客户端基础代码
// 服务端命令
thrift -gen php:server calculator.thrift
// 客户端命令
thrift -gen java calculator.thrift
- php 服务端实现计算器服务
<?php
/**
* Created by PhpStorm.
* Date: 18-1-6
* Time: 下午9:26
*/
namespace App\Services;
use App\Rpc\Learn\CalculatorIf;
use App\Rpc\Learn\Operation;
use App\Rpc\Learn\InvalidOperation;
class CalculatorService implements CalculatorIf {
/**
* @param double $num1
* @param double $num2
* @param int $op
* @return double
* @throws InvalidOperation
*/
public function calculate($num1, $num2, $op) {
switch ($op) {
case Operation::ADD:
$val = $num1 + $num2;
break;
case Operation::SUBTRACT:
$val = $num1 - $num2;
break;
case Operation::MULTIPLY:
$val = $num1 * $num2;
break;
case Operation::DIVIDE:
if ($num2 == 0) {
$io = new InvalidOperation();
$io->whatOp = $op;
$io->why = "Cannot divide by 0";
throw $io;
}
$val = $num1 / $num2;
break;
default:
$io = new InvalidOperation();
$io->whatOp = $op;
$io->why = "Invalid Operation";
throw $io;
}
return $val;
}
}
- 搭建并开启服务
本文使用了laravel 5.5 框架来搭建php 测试服务器,由composer管理系统依赖,为了引入 thrift 依赖,在项目根目录下执行以下命令即可:
composer require apache/thrift
编写 RpcController:
<?php
/**
* Created by PhpStorm.
* Date: 18-1-6
* Time: 下午9:16
*/
namespace App\Http\Controllers;
use App\Rpc\Learn\CalculatorProcessor;
use App\Services\CalculatorService;
use Illuminate\Http\Request;
use Thrift\Protocol\TBinaryProtocol;
use Thrift\Transport\TBufferedTransport;
use Thrift\Transport\TPhpStream;
class RpcController extends Controller
{
function handleRequest(Request $request) {
header('Content-Type', 'application/x-thrift');
$handler = new CalculatorService();
$processor = new CalculatorProcessor($handler);
$transport = new TBufferedTransport(new TPhpStream(TPhpStream::MODE_R | TPhpStream::MODE_W));
$protocol = new TBinaryProtocol($transport, true, true);
$transport->open();
$processor->process($protocol, $protocol);
$transport->close();
}
}
在 routes/api.php 文件中配置路由:
Route::post('/rpc', [
'as' => 'rpc',
'uses' => 'RpcController@handleRequest'
]);
在项目根目录下执行以下命令启动测试服务器:
php artisan serve
- 编写 Java rpc 客户端
thrift 0.11.0 版本目前尚未加入maven 仓库,因此使用以下方式将无法下载到thrift 0.11.0版本的依赖包
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.11.0</version>
</dependency>
目前如果要使用0.11.0版,在编译构建thrift源代码后,lib/java/build 目录下有所有需要依赖的jar包,将其加入类路径即可。
该例子中的客户端代码非常简单:
package app;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.THttpClient;
import org.apache.thrift.transport.TTransport;
import app.rpc.learn.Calculator;
import app.rpc.learn.InvalidOperation;
import app.rpc.learn.Operation;
public class RpcClient {
public static void main(String[] args) {
TTransport transport = null;
try {
transport = new THttpClient("http://localhost:8000/api/rpc");
TProtocol protocol = new TBinaryProtocol(transport, true, true);
Calculator.Client rpcCalculator = new Calculator.Client(protocol);
System.out.println("Start Access Calculate Service From PHP Rpc Server...");
System.out.print("12 + 5 = ");
System.out.println(rpcCalculator.calculate(12, 5, Operation.ADD));
System.out.print("12 - 5 = ");
System.out.println(rpcCalculator.calculate(12, 5, Operation.SUBTRACT));
System.out.print("12 * 5 = ");
System.out.println(rpcCalculator.calculate(12, 5, Operation.MULTIPLY));
System.out.print("12 / 5 = ");
System.out.println(rpcCalculator.calculate(12, 5, Operation.DIVIDE));
System.out.print("1 / 0 = ");
System.out.println(rpcCalculator.calculate(1, 0, Operation.DIVIDE));
} catch (InvalidOperation e) {
System.out.println("Exception: " + e.why);
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
if (transport != null) {
transport.close();
}
}
}
}
运行结果:
Start Access Calculate Service From PHP Rpc Server...
12 + 5 = 17.0
12 - 5 = 7.0
12 * 5 = 60.0
12 / 5 = 2.4
1 / 0 = Exception: Cannot divide by 0
最后感谢伟大的markdown让写文档如此方便!