IDL(Interface Definition Language) 接口定义语言来描述通用的服务接口, 并通过不同的语言代理来实现跨平台,不同语言的功能。
- ThriftIDL语法:
//命名空间,对应着java中的包,Thrift生成的类文件会在这个目录中
namespace java com.test
//数据结构
struct Parameter{
1: required i32 id;
2: required string name;
}
//service
service DemoService{
i32 demoMethod(1:string param1, 2:Parameter param2, 3:map<string,string> param3);
}
2.数据类型
* 基本类型:
bool: 布尔值
byte: 8位有符号整数
i16: 16位有符号整数
i32: 32位有符号整数
i64: 64位有符号整数
double: 64位浮点数
string: UTF-8编码的字符串
binary: 二进制串
* 结构体类型:
struct: 定义的结构体对象
* 容器类型:
list: 有序元素列表
set: 无序无重复元素集合
map: 有序的key/value集合
* 异常类型:
exception: 异常类型
* 服务类型:
service: 具体对应服务的类
thrift生成代码: thrift -r --gen java demo.thrift
,每一个struct,service都会单独生成一个类。我们需要implements DemoService.Iface来实现我们的功能。
自动生成接口有两个,一个同步调用的Iface,另外一个异步调用的AsyncIface。异步调用的接口多了一个AsyncMethodCallback参数。
public interface Iface {
public int demoMethod(String param1, Parameter param2, Map<String,String> param3) throws org.apache.thrift.TException;
}
public interface AsyncIface {
public void demoMethod(String param1, Parameter param2, Map<String,String> param3, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.demoMethod_call> resultHandler) throws org.apache.thrift.TException;
}
Client代码逻辑:
客户端的职能其实就是发送请求,等待结果。
从以下代码,我们可以看到demoMethod调用了send_demoMethod方法,来进行参数赋值,并调用sendBase方法,通过父类来调用服务器端。同样,通过父类的receiveBase方法来接收服务器返回的数据。
public static class Client extends org.apache.thrift.TServiceClient implements Iface {
public static class Factory implements org.apache.thrift.TServiceClientFactory<Client> {
public Factory() {}
public Client getClient(org.apache.thrift.protocol.TProtocol prot) {
return new Client(prot);
}
public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
return new Client(iprot, oprot);
}
}
public int demoMethod(String param1, Parameter param2, Map<String,String> param3) throws org.apache.thrift.TException
{
send_demoMethod(param1, param2, param3);
return recv_demoMethod();
}
public void send_demoMethod(String param1, Parameter param2, Map<String,String> param3) throws org.apache.thrift.TException
{
demoMethod_args args = new demoMethod_args();
args.setParam1(param1);
args.setParam2(param2);
args.setParam3(param3);
sendBase("demoMethod", args);
}
public int recv_demoMethod() throws org.apache.thrift.TException
{
demoMethod_result result = new demoMethod_result();
receiveBase(result, "demoMethod");
if (result.isSetSuccess()) {
return result.success;
}
throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "demoMethod failed: unknown result");
}
}
//org.apache.thrift.TServiceClient.sendBase,客户端的父类方法
protected void sendBase(String methodName, TBase args) throws TException {
// 发送消息头
oprot_.writeMessageBegin(new TMessage(methodName, TMessageType.CALL, ++seqid_));
// 发送消息体,由方法参数对象自己处理编解码
args.write(oprot_);
oprot_.writeMessageEnd();
oprot_.getTransport().flush();
}
protected void receiveBase(TBase result, String methodName) throws TException {
// 接收消息头
TMessage msg = iprot_.readMessageBegin();
if (msg.type == TMessageType.EXCEPTION) {
TApplicationException x = TApplicationException.read(iprot_);
iprot_.readMessageEnd();
throw x;
}
if (msg.seqid != seqid_) {
throw new TApplicationException(TApplicationException.BAD_SEQUENCE_ID, methodName + " failed: out of sequence response");
}
//由返回值对象自己处理编解码
result.read(iprot_);
iprot_.readMessageEnd();
}
网友评论