天天看點

java學習總結——Apache thrift服務端與用戶端的建立

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);//需要等待傳回,不然用戶端會直接結束;用戶端結束後就接收不到傳回的結果了