Thrift文件
namespace java calculator
// 枚举类型
enum Operator{
ADD,SUB,MUL,DIV
}
// 异常类型(一种特殊的结构体)
exception InvalidationOperator{
1: i32 what,
2: string why
}
// 结构体
struct Work{
1: i32 num1,
2: i32 num2,
3: Operator op
}
// 服务
service Calculator{
// 方法定义:类型 方法名(num:变量类型 变量名) throws (num:异常类型 异常变量名)
i32 calculate(1: Work work) throws (1:InvalidationOperator e)
}
服务端代码
实现Thrift文件中定义的服务接口:
import calculator.Work;
import calculator.Calculator.Iface;
import calculator.InvalidationOperator;
class CalHandler implements Iface{
@Override
public int calculate(Work work) throws InvalidationOperator, TException {
switch(work.op){
case ADD:
return work.num1 + work.num2;
case SUB:
return work.num1 - work.num2;
case MUL:
return work.num1*work.num2;
case DIV:
if(work.num2 == 0){
throw new InvalidationOperator(work.op.getValue(), "0不能为除数!");
}
return work.num1/work.num2;
default:
throw new InvalidationOperator(work.op.getValue(), "未知操作符!");
}
}
}
其中
Iface的定义如下所示:
public interface Iface {
public int calculate(Work work) throws InvalidationOperator, org.apache.thrift.TException;
}
public interface AsyncIface {
public void calculate(Work work, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
}
实现服务器监听服务:
public class CalServer {
public static void main(String[] args) throws TTransportException{
TServerTransport transport = new TServerSocket(9999);
CalHandler cal = new CalHandler();
Processor<CalHandler> processor = new Processor<CalHandler>(cal);
TServer server = new TSimpleServer(new Args(transport).processor(processor));
System.out.println("服务器已开启...");
server.serve();
}
}
Thrift的
网络栈如下所示:
+-------------------------------------------+
| Server |
| (single-threaded, event-driven etc) |
+-------------------------------------------+
| Processor |
| (compiler generated) |
+-------------------------------------------+
| Protocol |
| (JSON, compact etc) |
+-------------------------------------------+
| Transport |
| (raw TCP, HTTP etc) |
+-------------------------------------------+
- Transport是对底层数据传输的抽象(abstraction for reading/writing from/to the network),实现了数据传输与数据(反)序列化的解耦。除了典型的socket数据传输方式(TServerSocket)外,Thrift还支持硬盘文件读写(TFileTransport)、缓存读写(TBufferedTransport)、按帧读写(TFramedTransport)、内存读写(TMemoryBuffer)等。
- Protocol定义了内存中的数据格式(in-memory data structures)转换为传输数据格式(wire-format)的方式,换句话说,协议定义了顶层的数据类型与Transport层数据的转换方式(how datatypes use the underlying Transport to encode/decode themselves)。常用的协议包括:JSON,XML,plain text,compact binary等。
- Processor负责从流中读写数据,Processor的构造函数如下所示:
public static class Processor<I extends Iface> {
public Processor(I iface) { }
protected Processor(I iface, Map<String, ProcessFunction> processMap) { }
}
public static class AsyncProcessor<I extends AsyncIface> {
public AsyncProcessor(I iface) { }
protected AsyncProcessor(I iface, Map<String, AsyncProcessFunction> processMap) { }
<span style="white-space:pre"> </span>
}
- Server综合以上所有东西对外提供服务
- 创建一个Transport
- 执行基于Transport的数据传输协议
- 创建基于数据传输协议以及数据传输逻辑的Processor
- 启动服务,监听客户端请求
客户端代码
public class CalClient {
public static void main(String[] args) throws InvalidationOperator, TException{
TTransport transport = new TSocket("localhost", 9999);
transport.open();
TProtocol protocol = new TBinaryProtocol(transport);
Client client = new Client(protocol);
Work work = new Work(1,2,Operator.ADD);
int rst = client.calculate(work);
System.out.println("结果:"+rst);
transport.close();
}
}