美文网首页
Thrift之IDL和生成代码

Thrift之IDL和生成代码

作者: 薛云龙 | 来源:发表于2019-02-21 11:35 被阅读0次

    IDL(Interface Definition Language) 接口定义语言来描述通用的服务接口, 并通过不同的语言代理来实现跨平台,不同语言的功能。

    1. 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来实现我们的功能。

    thrift生成代码
    自动生成接口有两个,一个同步调用的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();
     }
    

    参考文章:
    Thrift IDL - 数据类型和服务定义
    IDL和生成代码分析

    相关文章

      网友评论

          本文标题:Thrift之IDL和生成代码

          本文链接:https://www.haomeiwen.com/subject/ypalyqtx.html