thrift的使用分為三個步驟:
1、建立接口描述檔案,即demo.thrift檔案;
2、通過thrift檔案生成代碼。(這個過程需要安裝thrift的編譯環境,過程有些繁瑣。thrift使用C++編寫的,是以編譯環境是C++的環境。編譯環境教程可以網上找,挺多的。)
生成代碼指令:thrift -r -gen java -out "生成代碼所在目錄(目錄必須存在)" thriftFileName。
-r : 遞歸尋找檔案,一般在thrift檔案中有引用其他檔案的thrift檔案時使用
-gen :指定生成的目智語言
-out :執行生成源代碼的路徑,也可以不指定,預設目前目錄
注:1、用于生成代碼的thrift檔案可以在如下連結中獲得:點選打開連結
3、編寫服務端和用戶端。(使用的是org.apache.thrift-0.11.0版本,不同版本的在用戶端與服務端代碼編寫時,代碼會有差異,但是核心都是由TTransport,TProtocol,TServer三個部分組成的。)
thrift服務端的建立:
//根據生成的代碼建立processor。
//注:CalculatorHandler實作了Calculator.Iface接口,自定義了接口方法實作。
// Calculator.Iface是根據thrift檔案中的定義内容生成的,需要自行成代碼
CalculatorHandler handler = new CalculatorHandler();
Calculator.Processor processor = new Calculator.Processor(handler);
//服務端的建立,下面的每一個方法都一種服務端的建立方式,在外部直接調用就可以啟動服務
public static void simple(Calculator.Processor processor) throws Exception{
TServerTransport tServerTransport = new TServerSocket(9090);
TServer tServer = new TSimpleServer(new TServer.Args(tServerTransport)
.processor(processor) //Transport和Protocol,用戶端與服務端應該保持一緻
.inputProtocolFactory(new TCompactProtocol.Factory())
.outputProtocolFactory(new TCompactProtocol.Factory())
.inputTransportFactory(new TZlibTransport.Factory())
.outputTransportFactory(new TZlibTransport.Factory()));
System.out.println("listen port 9090,Starting the simple server...");
tServer.serve();
}
public static void noblock(Calculator.Processor processor) throws Exception{
/**
* 非阻塞的socket,必須使用TFramedTransport和TCompactProtocol
* 作為其Transport和Protocol
*/
TNonblockingServerSocket socket = new TNonblockingServerSocket(9092);
TFramedTransport.Factory tframeFactory = new TFramedTransport.Factory();
TCompactProtocol.Factory tCompactProtocol = new TCompactProtocol.Factory();
TServer server = new THsHaServer(
new THsHaServer.Args(socket)
.processor(processor)//Transport和Protocol,用戶端與服務端應該保持一緻
.inputProtocolFactory(tCompactProtocol)
.inputTransportFactory(tframeFactory)
.outputProtocolFactory(tCompactProtocol)
.outputTransportFactory(tframeFactory));
System.out.println("listen port 9092,Starting the noblock server...");
server.serve();
}
public static void asynServer(Calculator.Processor processor) throws Exception{
/**
* 非阻塞的socket,必須使用TFramedTransport和TCompactProtocol
* 作為其Transport和Protocol
*/
TNonblockingServerSocket tServerTransport = new TNonblockingServerSocket(9093);
TServer tServer = new TThreadedSelectorServer(new TThreadedSelectorServer.Args(tServerTransport)
.processor(processor)//Transport和Protocol,用戶端與服務端應該保持一緻
.inputProtocolFactory(new TCompactProtocol.Factory())
.outputProtocolFactory(new TCompactProtocol.Factory())
.inputTransportFactory(new TFramedTransport.Factory())
.outputTransportFactory(new TFramedTransport.Factory()));
System.out.println("listen port 9093,Starting the asynServer server...");
tServer.serve();
}
public static void asynThreadPoolServer(Calculator.Processor processor) throws Exception{
TNonblockingServerSocket tServerTransport = new TNonblockingServerSocket(9094);
TServer tServer = new TThreadPoolServer(new TThreadPoolServer.Args(tServerTransport)
.processor(processor)
.inputProtocolFactory(new TCompactProtocol.Factory())
.outputProtocolFactory(new TCompactProtocol.Factory())
.inputTransportFactory(new TFastFramedTransport.Factory())
.outputTransportFactory(new TFastFramedTransport.Factory()));
System.out.println("listen port 9094,Starting the asynThreadPoolServer server...");
tServer.serve();
}
public static void tNonblockingServer(Calculator.Processor processor) throws Exception{
TNonblockingServerSocket tServerTransport = new TNonblockingServerSocket(9095);
TServer tServer = new TNonblockingServer(new TNonblockingServer.Args(tServerTransport)
.processor(processor)//Transport和Protocol,用戶端與服務端應該保持一緻
.inputProtocolFactory(new TCompactProtocol.Factory())
.outputProtocolFactory(new TCompactProtocol.Factory())
.inputTransportFactory(new TFastFramedTransport.Factory())
.outputTransportFactory(new TFastFramedTransport.Factory()));
System.out.println("listen port 9095,Starting the tNonblockingServer server...");
tServer.serve();
}
thrfit用戶端的建立:
/**同步調用的用戶端*/
TTransport tTransport= new TSocket("localhost",9092);
tTransport = new TFramedTransport.Factory().getTransport(tTransport);
tTransport.open();
TProtocol tProtocol = new TCompactProtocol(tTransport);
//注:建立服務端,調用方法。Calculator類和Work類都是根據thrift檔案生成的類
Calculator.Client client = new Calculator.Client(tProtocol);
Work work = new Work();
work.op = Operation.DIVIDE;
work.num1 = 1;
work.num2 = 0;
try {
int calculate = client.calculate(1, work);
System.out.println("Whoa we can divide by 0");
}catch (invalidOperation ex ){
System.out.println("Invalid operation: " + ex.why);
}
/**異步調用的用戶端*/
TAsyncClientManager clientManager = new TAsyncClientManager();
TProtocolFactory protocolFactory = new TCompactProtocol.Factory();
TNonblockingSocket socket = new TNonblockingSocket("localhost",9093);
Calculator.AsyncClient client = new Calculator.AsyncClient(protocolFactory,clientManager,socket);
ResultHandler resultHandler = new ResultHandler(); //自定義類,使用者回調處理,實作了AsyncMethodCallback接口
Work work = new Work();
work.op = Operation.SUBTRACT;
work.num1 = 15;
work.num2 = 10;
try {
client.calculate(1, work,resultHandler);
}catch (invalidOperation ex ){
System.out.println("Invalid operation: " + ex.why);
}
Thread.sleep(5000);//需要等待傳回,不然用戶端會直接結束;用戶端結束後就接收不到傳回的結果了