posts - 156,  comments - 601,  trackbacks - 0
          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(truetrue);
                  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(truetrue);
          //        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!

          posted on 2011-11-12 18:57 x.matthew 閱讀(17897) 評論(4)  編輯  收藏 所屬分類: Best Practise(JDK API)
          主站蜘蛛池模板: 随州市| 铜鼓县| 甘南县| 盐津县| 井陉县| 辽阳市| 吴川市| 临汾市| 阳信县| 普洱| 台州市| 确山县| 石渠县| 水富县| 红河县| 云龙县| 玉门市| 凤山市| 比如县| 青河县| 南江县| 安陆市| 安吉县| 历史| 雷波县| 竹山县| 霸州市| 新津县| 慈溪市| 尼木县| 盱眙县| 马尔康县| 永丰县| 庆阳市| 怀远县| 方城县| 盈江县| 比如县| 泽普县| 乡宁县| 财经|