thrift的使用中一般是一个Server对应一个Processor和一个Transport,如果有多个服务的话,那必须要启动多个Server,占用多个端口,这种方式显然不是我们想要的,所以thrift为我们提供了复用端口的方式,通过监听一个端口就可以提供多种服务,这种方式需要用到两个类:TMultiplexedProcessor和TMultiplexedProtocol。
创建 2 个 Laravel 项目,thrift-server (服务端) 和 thrift-client (客户端)
testServer.thrift:
namespace php Rpc.Test
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),
string echoString(1: string str) ,
}
service Echo {
string echo(1: string str) ,
}
每个service类对应一种服务,服务类下可有多个方法。
thrift-server根目录生成客户端类命令:
thrift -r --out ./ --gen php thriftSource/testServer.thrift
将生成的Rpc/Test文件夹剪切到thrift-client项目的Rpc目录中
在thrift-server根目录继续生成服务端类:
thrift -r --out ./ --gen php:server thriftSource/testServer.thrift
根目录创建Service目录,存放实现Calculator和Echo类的文件
Service/CalculatorService.php
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;
}
/**
* @param $string
*/
public function echoString($string) {
return $string;
}
}
Service/EchoService.php:
thrift-server服务端控制器:
registerProcessor("calculator", $calculatorProcessor);
$multiplexedProcessor->registerProcessor("echo", $echoProcessor);
// 初始化数据传输方式transport
$transport = new TBufferedTransport(new TPhpStream(TPhpStream::MODE_R | TPhpStream::MODE_W));
// 利用该传输方式初始化数据传输格式protocol
$protocol = new TBinaryProtocol($transport, true, true);
// 开始服务
$transport->open();
$multiplexedProcessor->process($protocol, $protocol);
$transport->close();
} catch (TException $tx) {
print 'TException: '.$tx->getMessage()."\n";
}
}
}
配置post方式路由
Route::post('/rpc/server', 'ServerController@handleManyRequest');
配置虚拟主机 8081 端口监听thrift-server服务,80端口监听thrift-client服务
thrift-client客户端控制器:
open();
// 调用接口方法
$sum = $calculatorClient->calculate(1, 2, Operation::ADD);
print "calculator service -> calculate function -> 1+2=$sum ";
$test = $calculatorClient->echoString('this it test');
print "calculator service -> echoString function -> echoString:$test ";
$echoString = $echoClient->echo('echo method');
print "echo service -> echo function -> echo:$echoString\n\r";
$transport->close();
} catch (TException $tx) {
print 'TException: '.$tx->getMessage()."\n";
}
}
}
由此可客户端可调用服务端的方法,实现通讯:
注意:
1、根目录新建目录需配置composer.json中的psr-4
2、取消http/kernel.php中web中间件内容