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 閱讀(17898) 評論(4)  編輯  收藏 所屬分類: Best Practise(JDK API)
          主站蜘蛛池模板: 河池市| 区。| 辽阳市| 芦山县| 紫金县| 红河县| 阿拉善盟| 黔南| 阳春市| 闻喜县| 廉江市| 日土县| 曲周县| 太和县| 孟州市| 金昌市| 镇原县| 涞源县| 乌鲁木齐市| 防城港市| 永善县| 马关县| 紫金县| 广元市| 资兴市| 辉县市| 白城市| 霍州市| 台中市| 潜江市| 奉化市| 敦煌市| 滨州市| 通道| 五莲县| 汤原县| 武宣县| 柞水县| 磴口县| 竹溪县| 临武县|