Thrift学习笔记(原创)

Thrift学习笔记(原创)
Thrift出自Facebook用于后台各个服务间的通讯,Thrift的设计强调统一的编程接口的多语言通讯框架.

下面将通过一个实例来讲解Thrift的使用方法:

1. 定义 idl文件,用来描述将要生成的数据通讯内容API接口,以下面一个简单例子来说明service.idl
namespace java com.xmatthew.thrift.demo

struct Info {
  
1 : string key ,
  
2 : binary value ,
}

service    DemoService{
    void add(
1 :string key ,   2 :binary value) ;
    binary get( 1 :string key) ,
}
说明:
namespace 表示目录结构,生成java时会产生java的package
struct 表示数据结构体,在java下是一个bean对象,在c则对应struct结构
service 表示服务类, 在java会生成DemoService.java。 提供两个接口方法,客户端和服务端都会拥有

2. 生成特定语言源文件,下面以java为例

thrift-0.6.0.exe -r --gen java service.idl

运行成功后,会生成gen-java文件,下面就是源码文件
本例中会产生两个文件
Info.java
DemoService.java

3. 开发客户端
有了这两个文件后,接下来就需要把thrift的java类库引进来,就可以开发客户端部分了

首先新建一个LocalClient类,继承于DemoServer.Client类,源码如下:
import  org.apache.thrift.protocol.TProtocol;
import  org.apache.thrift.transport.TTransport;
import  org.apache.thrift.transport.TTransportException;

import  com.xmatthew.thrift.demo.DemoService.Client;

/**
 * 
@author  xiemalin
 *
 
*/
public   class  LocalClient  extends  Client {
    
private  TTransport transport;
    
    
public  LocalClient(TProtocol prot, int  port, TTransport ftransport)  throws  TTransportException {
        
super (prot);
        
this .transport   =  ftransport;
    }
    
    
public   void  close(){
        
this .transport.close();
    }
    

}

接下来为了方便使用,创建一个工厂类, 包括main方法,进行使用示例
import  java.io.IOException;
import  java.nio.ByteBuffer;

import  org.apache.thrift.TException;
import  org.apache.thrift.protocol.TBinaryProtocol;
import  org.apache.thrift.protocol.TProtocol;
import  org.apache.thrift.transport.TSocket;
import  org.apache.thrift.transport.TTransportException;

public   class  ClientFactory {

    
public   static  LocalClient getClient(String ip, int  port)  throws  TTransportException, IOException{
        TSocket transport 
=   new  TSocket(ip,port);
        
        TProtocol protocol 
=   new  TBinaryProtocol(transport);
        transport.open();
        LocalClient client 
=   new  LocalClient(protocol, port,transport) ;
        
return  client;
    }
    
    
    
public   static   void  main(String[] args)  throws  IOException, TException {
        LocalClient client 
=  ClientFactory.getClient( " localhost " 8900 );
        ByteBuffer bb 
=  ByteBuffer.wrap( " Hello " .getBytes());
        client.add(
" abc " , bb);
        System.out.println(
" ok " );
        
        System.out.println(
new  String(client.get( " aaa " ).array()));
    }
}

这样客户端部分已经开发完成,非常快。

4. 开发服务器端部分, 新建一个Server 类, 该类实现于 DemoService.Iface接口(实现要求的两个方法即可)
这里代码中,可需要使用thrift的类库,开启Socket服务即可。
完整源代码如下:
import  java.nio.ByteBuffer;

import  org.apache.thrift.TException;
import  org.apache.thrift.protocol.TBinaryProtocol;
import  org.apache.thrift.protocol.TBinaryProtocol.Factory;
import  org.apache.thrift.server.TThreadPoolServer;
import  org.apache.thrift.server.TThreadPoolServer.Args;
import  org.apache.thrift.transport.TServerSocket;
import  org.apache.thrift.transport.TServerTransport;
import  org.apache.thrift.transport.TTransportException;

import  com.xmatthew.thrift.demo.DemoService;
import  com.xmatthew.thrift.demo.DemoService.Iface;

public   class  Server  implements  Iface {
    
    
private   final   int  port ;
    
    
private   final  TThreadPoolServer tr_server;
    
    
public  Server( int  _port)  throws  TTransportException{
        
this .port  =  _port;
        Factory protoFactory 
=   new  TBinaryProtocol.Factory( true true );
        TServerTransport serverTransport 
=   new  TServerSocket(port);
        DemoService.Processor processor 
=   new  DemoService.Processor( this );
        tr_server 
=   new  TThreadPoolServer( new  Args(serverTransport).processor(processor)
                .protocolFactory(protoFactory));
    }

    
public   void  run(){
        tr_server.serve();
    }
    
    
public   synchronized   void  close(){
        tr_server.stop();
    }

    
public   void  add(String key, ByteBuffer value)  throws  TException {
       System.out.println(
" invoke 'add'( " + key + " , " + new  String(value.array()) + " ) " );
        
    }

    
public  ByteBuffer get(String key)  throws  TException {
        System.out.println(
" invoke 'set'( " + key + " ) " );
        ByteBuffer bb 
=  ByteBuffer.wrap( " get success " .getBytes());
        
return  bb;
    }


    
public   static   void  main(String[] args)  throws  TTransportException {
        Server server 
=   new  Server( 8900 );
        server.run();
    }
}

thrift提供各种服务监听服务,包括传统IO, New IO, Http方式. 还提供线程池的监听服务等。
下面是使用线程池的nio方式用法
注:在使用NIO时,客户端需要使用TFramedTransport,进行数据传输
// 客户端代码
     public   static  LocalClient getClient(String ip, int  port)  throws  TTransportException, IOException{
        TSocket transport 
=   new  TSocket(ip,port);
        TFramedTransport tt 
=   new  TFramedTransport(transport);
        TProtocol protocol 
=   new  TBinaryProtocol(tt);
        tt.open();
        LocalClient client 
=   new  LocalClient(protocol, port, tt) ;
        
return  client;
    }

// 服务器端代码
     public  Server( int  _port)  throws  TTransportException{
        
this .port  =  _port;
        Factory protoFactory 
=   new  TBinaryProtocol.Factory( true true );
//         TServerTransport serverTransport = new TServerSocket(port);
        DemoService.Processor processor  =   new  DemoService.Processor( this );
//         tr_server = new TThreadPoolServer(new Args(serverTransport).processor(processor)
//                 .protocolFactory(protoFactory));
        
        TNonblockingServerTransport nioTransport 
=   new  TNonblockingServerSocket(port);
        tr_server 
=   new  TNonblockingServer( new  Args(nioTransport).processor(processor)
                .protocolFactory(protoFactory));
    }



5. 下面就可以分别运行 main方法,进行测试即可。


Good Luck!
Yours Matthew!

你可能感兴趣的:(Thrift学习笔记(原创))