Thrift入门及Java实例演示

目录:
  • 概述
  • 下载配置
  • 基本概念
    1. 数据类型
    2. 服务端编码基本步骤
    3. 客户端编码基本步骤
    4. 数据传输协议
  • 实例演示(java)
    1.  thrift生成代码
    2.  实现接口Iface
    3. TSimpleServer服务模型
    4. TThreadPoolServer 服务模型
    5. TNonblockingServer 服务模型
    6. THsHaServer服务模型
    7. 异步客户端

[一]、概述

Thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 等等编程语言间无缝结合的、高效的服务。

Thrift最初由facebook开发,07年四月开放源码,08年5月进入apache孵化器。thrift允许你定义一个简单的定义文件中的数据类型和服务接口。以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。

官网地址:thrift.apache.org

推荐值得一看的文章:

[二]、下载配置

到官网下载最新版本,截止今日(2012-06-11)最新版本为0.8.0.

1. 如果是Maven构建项目的,直接在pom.xml 中添加如下内容:

  1. <dependency>  
  2.   <groupId>org.apache.thrift</groupId>  
  3.   <artifactId>libthrift</artifactId>  
  4.   <version>0.8.0</version>  
  5. </dependency>  
<dependency>
  <groupId>org.apache.thrift</groupId>
  <artifactId>libthrift</artifactId>
  <version>0.8.0</version>
</dependency>

2.如果自己编译lib包,把下载的压缩包解压到X:盘,然后在X:\thrift-0.8.0\lib\java 目录下运行ant进行自动编译,会在X:\thrift-0.8.0\lib\java\build\ 目录下看到编译好的lib包:libthrift-0.8.0.jar

[三]、基本概念

1.数据类型

  • 基本类型:
    • bool:布尔值,true 或 false,对应 Java 的 boolean
    • byte:8 位有符号整数,对应 Java 的 byte
    • i16:16 位有符号整数,对应 Java 的 short
    • i32:32 位有符号整数,对应 Java 的 int
    • i64:64 位有符号整数,对应 Java 的 long
    • double:64 位浮点数,对应 Java 的 double
    • string:utf-8编码的字符串,对应 Java 的 String
  • 结构体类型:
    • struct:定义公共的对象,类似于 C 语言中的结构体定义,在 Java 中是一个 JavaBean
  • 容器类型:
    • list:对应 Java 的 ArrayList
    • set:对应 Java 的 HashSet
    • map:对应 Java 的 HashMap
  • 异常类型:
    • exception:对应 Java 的 Exception
  • 服务类型:
    • service:对应服务的类

2.服务端编码基本步骤:

  • 实现服务处理接口impl
  • 创建TProcessor
  • 创建TServerTransport
  • 创建TProtocol
  • 创建TServer
  • 启动Server

3.客户端编码基本步骤:

  • 创建Transport
  • 创建TProtocol
  • 基于TTransport和TProtocol创建 Client
  • 调用Client的相应方法

4.数据传输协议

  • TBinaryProtocol : 二进制格式.
  • TCompactProtocol : 压缩格式
  • TJSONProtocol : JSON格式
  • TSimpleJSONProtocol : 提供JSON只写协议, 生成的文件很容易通过脚本语言解析

tips:客户端和服务端的协议要一致

[四]、实例演示

1. thrift生成代码

创建Thrift文件:G:\test\thrift\demoHello.thrift ,内容如下:

  1. namespace java com.micmiu.thrift.demo  
  2. service  HelloWorldService {  
  3.   string sayHello(1:string username)  
  4. }  
namespace java com.micmiu.thrift.demo
service  HelloWorldService {
  string sayHello(1:string username)
}

目录结构如下:

  1. G:\test\thrift>tree /F  
  2. 卷 other 的文件夹 PATH 列表  
  3. 卷序列号为 D238-BE47  
  4. G:.  
  5.     demoHello.thrift  
  6.     demouser.thrift  
  7.     thrift-0.8.0.exe  
  8.   
  9. 没有子文件夹  
G:\test\thrift>tree /F
卷 other 的文件夹 PATH 列表
卷序列号为 D238-BE47
G:.
    demoHello.thrift
    demouser.thrift
    thrift-0.8.0.exe

没有子文件夹

thrift-0.8.0.exe 是官网提供的windows下编译工具,运用这个工具生成相关代码:

thrift-0.8.0.exe -r -gen java ./demoHello.thrift

生成后的目录结构如下:

  1. G:\test\thrift>tree /F  
  2. 卷 other 的文件夹 PATH 列表  
  3. 卷序列号为 D238-BE47  
  4. G:.  
  5. │  demoHello.thrift  
  6. │  demouser.thrift  
  7. │  thrift-0.8.0.exe  
  8. │  
  9. └─gen-java  
  10.     └─com  
  11.         └─micmiu  
  12.             └─thrift  
  13.                 └─demo  
  14.                         HelloWorldService.java  
G:\test\thrift>tree /F
卷 other 的文件夹 PATH 列表
卷序列号为 D238-BE47
G:.
│  demoHello.thrift
│  demouser.thrift
│  thrift-0.8.0.exe
│
└─gen-java
    └─com
        └─micmiu
            └─thrift
                └─demo
                        HelloWorldService.java

将生成的HelloWorldService.java 文件copy到自己测试的工程中,我的工程是用maven构建的,故在pom.xml中增加如下内容:

  1. <dependency>  
  2.     <groupId>org.apache.thrift</groupId>  
  3.     <artifactId>libthrift</artifactId>  
  4.     <version>0.8.0</version>  
  5. </dependency>  
  6. <dependency>  
  7.     <groupId>org.slf4j</groupId>  
  8.     <artifactId>slf4j-log4j12</artifactId>  
  9.     <version>1.5.8</version>  
  10. </dependency>  
<dependency>
	<groupId>org.apache.thrift</groupId>
	<artifactId>libthrift</artifactId>
	<version>0.8.0</version>
</dependency>
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-log4j12</artifactId>
	<version>1.5.8</version>
</dependency>

2. 实现接口Iface

java代码:HelloWorldImpl.java

  1. package com.micmiu.thrift.demo;  
  2.   
  3. import org.apache.thrift.TException;  
  4.   
  5. /** 
  6.  * blog http://www.micmiu.com 
  7.  * 
  8.  * @author Michael 
  9.  * 
  10.  */  
  11. public class HelloWorldImpl implements HelloWorldService.Iface {  
  12.   
  13.     public HelloWorldImpl() {  
  14.     }  
  15.   
  16.     @Override  
  17.     public String sayHello(String username) throws TException {  
  18.         return "Hi," + username + " welcome to my blog www.micmiu.com";  
  19.     }  
  20.   
  21. }  
package com.micmiu.thrift.demo;

import org.apache.thrift.TException;

/**
 * blog http://www.micmiu.com
 *
 * @author Michael
 *
 */
public class HelloWorldImpl implements HelloWorldService.Iface {

	public HelloWorldImpl() {
	}

	@Override
	public String sayHello(String username) throws TException {
		return "Hi," + username + " welcome to my blog www.micmiu.com";
	}

}

3.TSimpleServer服务端

简单的单线程服务模型,一般用于测试。

编写服务端server代码:HelloServerDemo.java

  1. package com.micmiu.thrift.demo;  
  2.   
  3. import org.apache.thrift.TProcessor;  
  4. import org.apache.thrift.protocol.TBinaryProtocol;  
  5. import org.apache.thrift.protocol.TCompactProtocol;  
  6. import org.apache.thrift.protocol.TJSONProtocol;  
  7. import org.apache.thrift.protocol.TSimpleJSONProtocol;  
  8. import org.apache.thrift.server.TServer;  
  9. import org.apache.thrift.server.TSimpleServer;  
  10. import org.apache.thrift.transport.TServerSocket;  
  11.   
  12. /** 
  13.  * blog http://www.micmiu.com 
  14.  * 
  15.  * @author Michael 
  16.  * 
  17.  */  
  18. public class HelloServerDemo {  
  19.     public static final int SERVER_PORT = 8090;  
  20.   
  21.     public void startServer() {  
  22.         try {  
  23.             System.out.println("HelloWorld TSimpleServer start ....");  
  24.   
  25.             TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(  
  26.                     new HelloWorldImpl());  
  27.             // HelloWorldService.Processor<HelloWorldService.Iface> tprocessor =  
  28.             // new HelloWorldService.Processor<HelloWorldService.Iface>(  
  29.             // new HelloWorldImpl());  
  30.   
  31.             // 简单的单线程服务模型,一般用于测试  
  32.             TServerSocket serverTransport = new TServerSocket(SERVER_PORT);  
  33.             TServer.Args tArgs = new TServer.Args(serverTransport);  
  34.             tArgs.processor(tprocessor);  
  35.             tArgs.protocolFactory(new TBinaryProtocol.Factory());  
  36.             // tArgs.protocolFactory(new TCompactProtocol.Factory());  
  37.             // tArgs.protocolFactory(new TJSONProtocol.Factory());  
  38.             TServer server = new TSimpleServer(tArgs);  
  39.             server.serve();  
  40.   
  41.         } catch (Exception e) {  
  42.             System.out.println("Server start error!!!");  
  43.             e.printStackTrace();  
  44.         }  
  45.     }  
  46.   
  47.     /** 
  48.      * @param args 
  49.      */  
  50.     public static void main(String[] args) {  
  51.         HelloServerDemo server = new HelloServerDemo();  
  52.         server.startServer();  
  53.     }  
  54.   
  55. }  
package com.micmiu.thrift.demo;

import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TJSONProtocol;
import org.apache.thrift.protocol.TSimpleJSONProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;

/**
 * blog http://www.micmiu.com
 *
 * @author Michael
 *
 */
public class HelloServerDemo {
	public static final int SERVER_PORT = 8090;

	public void startServer() {
		try {
			System.out.println("HelloWorld TSimpleServer start ....");

			TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(
					new HelloWorldImpl());
			// HelloWorldService.Processor<HelloWorldService.Iface> tprocessor =
			// new HelloWorldService.Processor<HelloWorldService.Iface>(
			// new HelloWorldImpl());

			// 简单的单线程服务模型,一般用于测试
			TServerSocket serverTransport = new TServerSocket(SERVER_PORT);
			TServer.Args tArgs = new TServer.Args(serverTransport);
			tArgs.processor(tprocessor);
			tArgs.protocolFactory(new TBinaryProtocol.Factory());
			// tArgs.protocolFactory(new TCompactProtocol.Factory());
			// tArgs.protocolFactory(new TJSONProtocol.Factory());
			TServer server = new TSimpleServer(tArgs);
			server.serve();

		} catch (Exception e) {
			System.out.println("Server start error!!!");
			e.printStackTrace();
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		HelloServerDemo server = new HelloServerDemo();
		server.startServer();
	}

}

编写客户端Client代码:HelloClientDemo.java

  1. package com.micmiu.thrift.demo;  
  2.   
  3. import org.apache.thrift.TException;  
  4. import org.apache.thrift.protocol.TBinaryProtocol;  
  5. import org.apache.thrift.protocol.TCompactProtocol;  
  6. import org.apache.thrift.protocol.TJSONProtocol;  
  7. import org.apache.thrift.protocol.TProtocol;  
  8. import org.apache.thrift.transport.TSocket;  
  9. import org.apache.thrift.transport.TTransport;  
  10. import org.apache.thrift.transport.TTransportException;  
  11.   
  12. /** 
  13.  * blog http://www.micmiu.com 
  14.  * 
  15.  * @author Michael 
  16.  * 
  17.  */  
  18. public class HelloClientDemo {  
  19.   
  20.     public static final String SERVER_IP = "localhost";  
  21.     public static final int SERVER_PORT = 8090;  
  22.     public static final int TIMEOUT = 30000;  
  23.   
  24.     /** 
  25.      * 
  26.      * @param userName 
  27.      */  
  28.     public void startClient(String userName) {  
  29.         TTransport transport = null;  
  30.         try {  
  31.             transport = new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT);  
  32.             // 协议要和服务端一致  
  33.             TProtocol protocol = new TBinaryProtocol(transport);  
  34.             // TProtocol protocol = new TCompactProtocol(transport);  
  35.             // TProtocol protocol = new TJSONProtocol(transport);  
  36.             HelloWorldService.Client client = new HelloWorldService.Client(  
  37.                     protocol);  
  38.             transport.open();  
  39.             String result = client.sayHello(userName);  
  40.             System.out.println("Thrify client result =: " + result);  
  41.         } catch (TTransportException e) {  
  42.             e.printStackTrace();  
  43.         } catch (TException e) {  
  44.             e.printStackTrace();  
  45.         } finally {  
  46.             if (null != transport) {  
  47.                 transport.close();  
  48.             }  
  49.         }  
  50.     }  
  51.   
  52.     /** 
  53.      * @param args 
  54.      */  
  55.     public static void main(String[] args) {  
  56.         HelloClientDemo client = new HelloClientDemo();  
  57.         client.startClient("Michael");  
  58.   
  59.     }  
  60.   
  61. }  
package com.micmiu.thrift.demo;

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

/**
 * blog http://www.micmiu.com
 *
 * @author Michael
 *
 */
public class HelloClientDemo {

	public static final String SERVER_IP = "localhost";
	public static final int SERVER_PORT = 8090;
	public static final int TIMEOUT = 30000;

	/**
	 *
	 * @param userName
	 */
	public void startClient(String userName) {
		TTransport transport = null;
		try {
			transport = new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT);
			// 协议要和服务端一致
			TProtocol protocol = new TBinaryProtocol(transport);
			// TProtocol protocol = new TCompactProtocol(transport);
			// TProtocol protocol = new TJSONProtocol(transport);
			HelloWorldService.Client client = new HelloWorldService.Client(
					protocol);
			transport.open();
			String result = client.sayHello(userName);
			System.out.println("Thrify client result =: " + result);
		} catch (TTransportException e) {
			e.printStackTrace();
		} catch (TException e) {
			e.printStackTrace();
		} finally {
			if (null != transport) {
				transport.close();
			}
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		HelloClientDemo client = new HelloClientDemo();
		client.startClient("Michael");

	}

}

先运行服务端程序,日志如下:

HelloWorld TSimpleServer start ....

再运行客户端调用程序,日志如下:

Thrify client result =: Hi,Michael welcome to my blog www.micmiu.com

测试成功,和预期的返回信息一致。

4.TThreadPoolServer 服务模型

线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求。

编写服务端代码:HelloServerDemo.java

  1. package com.micmiu.thrift.demo;  
  2.   
  3. import org.apache.thrift.TProcessor;  
  4. import org.apache.thrift.protocol.TBinaryProtocol;  
  5. import org.apache.thrift.server.TServer;  
  6. import org.apache.thrift.server.TThreadPoolServer;  
  7. import org.apache.thrift.transport.TServerSocket;  
  8.   
  9. /** 
  10.  * blog http://www.micmiu.com 
  11.  * 
  12.  * @author Michael 
  13.  * 
  14.  */  
  15. public class HelloServerDemo {  
  16.     public static final int SERVER_PORT = 8090;  
  17.   
  18.     public void startServer() {  
  19.         try {  
  20.             System.out.println("HelloWorld TThreadPoolServer start ....");  
  21.   
  22.             TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(  
  23.                     new HelloWorldImpl());  
  24.   
  25.              TServerSocket serverTransport = new TServerSocket(SERVER_PORT);  
  26.              TThreadPoolServer.Args ttpsArgs = new TThreadPoolServer.Args(  
  27.              serverTransport);  
  28.              ttpsArgs.processor(tprocessor);  
  29.              ttpsArgs.protocolFactory(new TBinaryProtocol.Factory());  
  30.   
  31.             // 线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求。  
  32.              TServer server = new TThreadPoolServer(ttpsArgs);  
  33.              server.serve();  
  34.   
  35.         } catch (Exception e) {  
  36.             System.out.println("Server start error!!!");  
  37.             e.printStackTrace();  
  38.         }  
  39.     }  
  40.   
  41.     /** 
  42.      * @param args 
  43.      */  
  44.     public static void main(String[] args) {  
  45.         HelloServerDemo server = new HelloServerDemo();  
  46.         server.startServer();  
  47.     }  
  48.   
  49. }  
package com.micmiu.thrift.demo;

import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TServerSocket;

/**
 * blog http://www.micmiu.com
 *
 * @author Michael
 *
 */
public class HelloServerDemo {
	public static final int SERVER_PORT = 8090;

	public void startServer() {
		try {
			System.out.println("HelloWorld TThreadPoolServer start ....");

			TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(
					new HelloWorldImpl());

			 TServerSocket serverTransport = new TServerSocket(SERVER_PORT);
			 TThreadPoolServer.Args ttpsArgs = new TThreadPoolServer.Args(
			 serverTransport);
			 ttpsArgs.processor(tprocessor);
			 ttpsArgs.protocolFactory(new TBinaryProtocol.Factory());

			// 线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求。
			 TServer server = new TThreadPoolServer(ttpsArgs);
			 server.serve();

		} catch (Exception e) {
			System.out.println("Server start error!!!");
			e.printStackTrace();
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		HelloServerDemo server = new HelloServerDemo();
		server.startServer();
	}

}

客户端Client代码和之前的一样,只要数据传输的协议一致即可,客户端测试成功,结果如下:

Thrify client result =: Hi,Michael welcome to my blog www.micmiu.com

5.TNonblockingServer 服务模型

使用非阻塞式IO,服务端和客户端需要指定 TFramedTransport 数据传输的方式。

编写服务端代码:HelloServerDemo.java

  1. package com.micmiu.thrift.demo;  
  2.   
  3. import org.apache.thrift.TProcessor;  
  4. import org.apache.thrift.protocol.TCompactProtocol;  
  5. import org.apache.thrift.server.TNonblockingServer;  
  6. import org.apache.thrift.server.TServer;  
  7. import org.apache.thrift.transport.TFramedTransport;  
  8. import org.apache.thrift.transport.TNonblockingServerSocket;  
  9.   
  10. /** 
  11.  * blog http://www.micmiu.com 
  12.  * 
  13.  * @author Michael 
  14.  * 
  15.  */  
  16. public class HelloServerDemo {  
  17.     public static final int SERVER_PORT = 8090;  
  18.   
  19.     public void startServer() {  
  20.         try {  
  21.             System.out.println("HelloWorld TNonblockingServer start ....");  
  22.   
  23.             TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(  
  24.                     new HelloWorldImpl());  
  25.   
  26.             TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(  
  27.                     SERVER_PORT);  
  28.             TNonblockingServer.Args tnbArgs = new TNonblockingServer.Args(  
  29.                     tnbSocketTransport);  
  30.             tnbArgs.processor(tprocessor);  
  31.             tnbArgs.transportFactory(new TFramedTransport.Factory());  
  32.             tnbArgs.protocolFactory(new TCompactProtocol.Factory());  
  33.   
  34.             // 使用非阻塞式IO,服务端和客户端需要指定TFramedTransport数据传输的方式  
  35.             TServer server = new TNonblockingServer(tnbArgs);  
  36.             server.serve();  
  37.   
  38.         } catch (Exception e) {  
  39.             System.out.println("Server start error!!!");  
  40.             e.printStackTrace();  
  41.         }  
  42.     }  
  43.   
  44.     /** 
  45.      * @param args 
  46.      */  
  47.     public static void main(String[] args) {  
  48.         HelloServerDemo server = new HelloServerDemo();  
  49.         server.startServer();  
  50.     }  
  51.   
  52. }  
package com.micmiu.thrift.demo;

import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.TNonblockingServer;
import org.apache.thrift.server.TServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;

/**
 * blog http://www.micmiu.com
 *
 * @author Michael
 *
 */
public class HelloServerDemo {
	public static final int SERVER_PORT = 8090;

	public void startServer() {
		try {
			System.out.println("HelloWorld TNonblockingServer start ....");

			TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(
					new HelloWorldImpl());

			TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(
					SERVER_PORT);
			TNonblockingServer.Args tnbArgs = new TNonblockingServer.Args(
					tnbSocketTransport);
			tnbArgs.processor(tprocessor);
			tnbArgs.transportFactory(new TFramedTransport.Factory());
			tnbArgs.protocolFactory(new TCompactProtocol.Factory());

			// 使用非阻塞式IO,服务端和客户端需要指定TFramedTransport数据传输的方式
			TServer server = new TNonblockingServer(tnbArgs);
			server.serve();

		} catch (Exception e) {
			System.out.println("Server start error!!!");
			e.printStackTrace();
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		HelloServerDemo server = new HelloServerDemo();
		server.startServer();
	}

}

编写客户端代码:HelloClientDemo.java

  1. package com.micmiu.thrift.demo;  
  2.   
  3. import org.apache.thrift.TException;  
  4. import org.apache.thrift.protocol.TCompactProtocol;  
  5. import org.apache.thrift.protocol.TProtocol;  
  6. import org.apache.thrift.transport.TFramedTransport;  
  7. import org.apache.thrift.transport.TSocket;  
  8. import org.apache.thrift.transport.TTransport;  
  9. import org.apache.thrift.transport.TTransportException;  
  10.   
  11. /** 
  12.  * blog http://www.micmiu.com 
  13.  * 
  14.  * @author Michael 
  15.  * 
  16.  */  
  17. public class HelloClientDemo {  
  18.   
  19.     public static final String SERVER_IP = "localhost";  
  20.     public static final int SERVER_PORT = 8090;  
  21.     public static final int TIMEOUT = 30000;  
  22.   
  23.     /** 
  24.      * 
  25.      * @param userName 
  26.      */  
  27.     public void startClient(String userName) {  
  28.         TTransport transport = null;  
  29.         try {  
  30.             transport = new TFramedTransport(new TSocket(SERVER_IP,  
  31.                     SERVER_PORT, TIMEOUT));  
  32.             // 协议要和服务端一致  
  33.             TProtocol protocol = new TCompactProtocol(transport);  
  34.             HelloWorldService.Client client = new HelloWorldService.Client(  
  35.                     protocol);  
  36.             transport.open();  
  37.             String result = client.sayHello(userName);  
  38.             System.out.println("Thrify client result =: " + result);  
  39.         } catch (TTransportException e) {  
  40.             e.printStackTrace();  
  41.         } catch (TException e) {  
  42.             e.printStackTrace();  
  43.         } finally {  
  44.             if (null != transport) {  
  45.                 transport.close();  
  46.             }  
  47.         }  
  48.     }  
  49.   
  50.     /** 
  51.      * @param args 
  52.      */  
  53.     public static void main(String[] args) {  
  54.         HelloClientDemo client = new HelloClientDemo();  
  55.         client.startClient("Michael");  
  56.   
  57.     }  
  58.   
  59. }  
package com.micmiu.thrift.demo;

import org.apache.thrift.TException;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;

/**
 * blog http://www.micmiu.com
 *
 * @author Michael
 *
 */
public class HelloClientDemo {

	public static final String SERVER_IP = "localhost";
	public static final int SERVER_PORT = 8090;
	public static final int TIMEOUT = 30000;

	/**
	 *
	 * @param userName
	 */
	public void startClient(String userName) {
		TTransport transport = null;
		try {
			transport = new TFramedTransport(new TSocket(SERVER_IP,
					SERVER_PORT, TIMEOUT));
			// 协议要和服务端一致
			TProtocol protocol = new TCompactProtocol(transport);
			HelloWorldService.Client client = new HelloWorldService.Client(
					protocol);
			transport.open();
			String result = client.sayHello(userName);
			System.out.println("Thrify client result =: " + result);
		} catch (TTransportException e) {
			e.printStackTrace();
		} catch (TException e) {
			e.printStackTrace();
		} finally {
			if (null != transport) {
				transport.close();
			}
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		HelloClientDemo client = new HelloClientDemo();
		client.startClient("Michael");

	}

}

客户端的测试成功,结果如下:Thrify client result =: Hi,Michael welcome to my blog www.micmiu.com

6.THsHaServer服务模型

半同步半异步的服务端模型,需要指定为: TFramedTransport 数据传输的方式。

编写服务端代码:HelloServerDemo.java

  1. package com.micmiu.thrift.demo;  
  2.   
  3. import org.apache.thrift.TProcessor;  
  4. import org.apache.thrift.protocol.TBinaryProtocol;  
  5. import org.apache.thrift.protocol.TCompactProtocol;  
  6. import org.apache.thrift.server.THsHaServer;  
  7. import org.apache.thrift.server.TNonblockingServer;  
  8. import org.apache.thrift.server.TServer;  
  9. import org.apache.thrift.server.TSimpleServer;  
  10. import org.apache.thrift.server.TThreadPoolServer;  
  11. import org.apache.thrift.transport.TFramedTransport;  
  12. import org.apache.thrift.transport.TNonblockingServerSocket;  
  13. import org.apache.thrift.transport.TServerSocket;  
  14.   
  15. /** 
  16.  * blog http://www.micmiu.com 
  17.  * 
  18.  * @author Michael 
  19.  * 
  20.  */  
  21. public class HelloServerDemo {  
  22.     public static final int SERVER_PORT = 8090;  
  23.   
  24.     public void startServer() {  
  25.         try {  
  26.             System.out.println("HelloWorld THsHaServer start ....");  
  27.   
  28.             TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(  
  29.                     new HelloWorldImpl());  
  30.   
  31.             TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(  
  32.                     SERVER_PORT);  
  33.             THsHaServer.Args thhsArgs = new THsHaServer.Args(tnbSocketTransport);  
  34.             thhsArgs.processor(tprocessor);  
  35.             thhsArgs.transportFactory(new TFramedTransport.Factory());  
  36.             thhsArgs.protocolFactory(new TBinaryProtocol.Factory());  
  37.   
  38.             //半同步半异步的服务模型  
  39.             TServer server = new THsHaServer(thhsArgs);  
  40.             server.serve();  
  41.   
  42.         } catch (Exception e) {  
  43.             System.out.println("Server start error!!!");  
  44.             e.printStackTrace();  
  45.         }  
  46.     }  
  47.   
  48.     /** 
  49.      * @param args 
  50.      */  
  51.     public static void main(String[] args) {  
  52.         HelloServerDemo server = new HelloServerDemo();  
  53.         server.startServer();  
  54.     }  
  55.   
  56. }  
package com.micmiu.thrift.demo;

import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.THsHaServer;
import org.apache.thrift.server.TNonblockingServer;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.transport.TServerSocket;

/**
 * blog http://www.micmiu.com
 *
 * @author Michael
 *
 */
public class HelloServerDemo {
	public static final int SERVER_PORT = 8090;

	public void startServer() {
		try {
			System.out.println("HelloWorld THsHaServer start ....");

			TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(
					new HelloWorldImpl());

			TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(
					SERVER_PORT);
			THsHaServer.Args thhsArgs = new THsHaServer.Args(tnbSocketTransport);
			thhsArgs.processor(tprocessor);
			thhsArgs.transportFactory(new TFramedTransport.Factory());
			thhsArgs.protocolFactory(new TBinaryProtocol.Factory());

			//半同步半异步的服务模型
			TServer server = new THsHaServer(thhsArgs);
			server.serve();

		} catch (Exception e) {
			System.out.println("Server start error!!!");
			e.printStackTrace();
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		HelloServerDemo server = new HelloServerDemo();
		server.startServer();
	}

}

客户端代码和上面 4 中的类似,只要注意传输协议一致以及指定传输方式为TFramedTransport

7.异步客户端

编写服务端代码:HelloServerDemo.java

  1. package com.micmiu.thrift.demo;  
  2.   
  3. import org.apache.thrift.TProcessor;  
  4. import org.apache.thrift.protocol.TCompactProtocol;  
  5. import org.apache.thrift.server.TNonblockingServer;  
  6. import org.apache.thrift.server.TServer;  
  7. import org.apache.thrift.transport.TFramedTransport;  
  8. import org.apache.thrift.transport.TNonblockingServerSocket;  
  9.   
  10. /** 
  11.  * blog http://www.micmiu.com 
  12.  * 
  13.  * @author Michael 
  14.  * 
  15.  */  
  16. public class HelloServerDemo {  
  17.     public static final int SERVER_PORT = 8090;  
  18.   
  19.     public void startServer() {  
  20.         try {  
  21.             System.out.println("HelloWorld TNonblockingServer start ....");  
  22.   
  23.             TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(  
  24.                     new HelloWorldImpl());  
  25.   
  26.             TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(  
  27.                     SERVER_PORT);  
  28.             TNonblockingServer.Args tnbArgs = new TNonblockingServer.Args(  
  29.                     tnbSocketTransport);  
  30.             tnbArgs.processor(tprocessor);  
  31.             tnbArgs.transportFactory(new TFramedTransport.Factory());  
  32.             tnbArgs.protocolFactory(new TCompactProtocol.Factory());  
  33.   
  34.             // 使用非阻塞式IO,服务端和客户端需要指定TFramedTransport数据传输的方式  
  35.             TServer server = new TNonblockingServer(tnbArgs);  
  36.             server.serve();  
  37.   
  38.         } catch (Exception e) {  
  39.             System.out.println("Server start error!!!");  
  40.             e.printStackTrace();  
  41.         }  
  42.     }  
  43.   
  44.     /** 
  45.      * @param args 
  46.      */  
  47.     public static void main(String[] args) {  
  48.         HelloServerDemo server = new HelloServerDemo();  
  49.         server.startServer();  
  50.     }  
  51.   
  52. }  
package com.micmiu.thrift.demo;

import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.TNonblockingServer;
import org.apache.thrift.server.TServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;

/**
 * blog http://www.micmiu.com
 *
 * @author Michael
 *
 */
public class HelloServerDemo {
	public static final int SERVER_PORT = 8090;

	public void startServer() {
		try {
			System.out.println("HelloWorld TNonblockingServer start ....");

			TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(
					new HelloWorldImpl());

			TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(
					SERVER_PORT);
			TNonblockingServer.Args tnbArgs = new TNonblockingServer.Args(
					tnbSocketTransport);
			tnbArgs.processor(tprocessor);
			tnbArgs.transportFactory(new TFramedTransport.Factory());
			tnbArgs.protocolFactory(new TCompactProtocol.Factory());

			// 使用非阻塞式IO,服务端和客户端需要指定TFramedTransport数据传输的方式
			TServer server = new TNonblockingServer(tnbArgs);
			server.serve();

		} catch (Exception e) {
			System.out.println("Server start error!!!");
			e.printStackTrace();
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		HelloServerDemo server = new HelloServerDemo();
		server.startServer();
	}

}

编写客户端Client代码:HelloAsynClientDemo.java

  1. package com.micmiu.thrift.demo;  
  2.   
  3. import java.util.concurrent.CountDownLatch;  
  4. import java.util.concurrent.TimeUnit;  
  5.   
  6. import org.apache.thrift.TException;  
  7. import org.apache.thrift.async.AsyncMethodCallback;  
  8. import org.apache.thrift.async.TAsyncClientManager;  
  9. import org.apache.thrift.protocol.TCompactProtocol;  
  10. import org.apache.thrift.protocol.TProtocolFactory;  
  11. import org.apache.thrift.transport.TNonblockingSocket;  
  12. import org.apache.thrift.transport.TNonblockingTransport;  
  13.   
  14. import com.micmiu.thrift.demo.HelloWorldService.AsyncClient.sayHello_call;  
  15.   
  16. /** 
  17.  * blog http://www.micmiu.com 
  18.  * 
  19.  * @author Michael 
  20.  * 
  21.  */  
  22. public class HelloAsynClientDemo {  
  23.   
  24.     public static final String SERVER_IP = "localhost";  
  25.     public static final int SERVER_PORT = 8090;  
  26.     public static final int TIMEOUT = 30000;  
  27.   
  28.     /** 
  29.      * 
  30.      * @param userName 
  31.      */  
  32.     public void startClient(String userName) {  
  33.         try {  
  34.             TAsyncClientManager clientManager = new TAsyncClientManager();  
  35.             TNonblockingTransport transport = new TNonblockingSocket(SERVER_IP,  
  36.                     SERVER_PORT, TIMEOUT);  
  37.   
  38.             TProtocolFactory tprotocol = new TCompactProtocol.Factory();  
  39.             HelloWorldService.AsyncClient asyncClient = new HelloWorldService.AsyncClient(  
  40.                     tprotocol, clientManager, transport);  
  41.             System.out.println("Client start .....");  
  42.   
  43.             CountDownLatch latch = new CountDownLatch(1);  
  44.             AsynCallback callBack = new AsynCallback(latch);  
  45.             System.out.println("call method sayHello start ...");  
  46.             asyncClient.sayHello(userName, callBack);  
  47.             System.out.println("call method sayHello .... end");  
  48.             boolean wait = latch.await(30, TimeUnit.SECONDS);  
  49.             System.out.println("latch.await =:" + wait);  
  50.         } catch (Exception e) {  
  51.             e.printStackTrace();  
  52.         }  
  53.         System.out.println("startClient end.");  
  54.     }  
  55.   
  56.     public class AsynCallback implements AsyncMethodCallback<sayHello_call> {  
  57.         private CountDownLatch latch;  
  58.   
  59.         public AsynCallback(CountDownLatch latch) {  
  60.             this.latch = latch;  
  61.         }  
  62.   
  63.         @Override  
  64.         public void onComplete(sayHello_call response) {  
  65.             System.out.println("onComplete");  
  66.             try {  
  67.                 // Thread.sleep(1000L * 1);  
  68.                 System.out.println("AsynCall result =:"  
  69.                         + response.getResult().toString());  
  70.             } catch (TException e) {  
  71.                 e.printStackTrace();  
  72.             } catch (Exception e) {  
  73.                 e.printStackTrace();  
  74.             } finally {  
  75.                 latch.countDown();  
  76.             }  
  77.         }  
  78.   
  79.         @Override  
  80.         public void onError(Exception exception) {  
  81.             System.out.println("onError :" + exception.getMessage());  
  82.             latch.countDown();  
  83.         }  
  84.     }  
  85.   
  86.     /** 
  87.      * @param args 
  88.      */  
  89.     public static void main(String[] args) {  
  90.         HelloAsynClientDemo client = new HelloAsynClientDemo();  
  91.         client.startClient("Michael");  
  92.   
  93.     }  
  94.   
  95. }  
package com.micmiu.thrift.demo;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import org.apache.thrift.TException;
import org.apache.thrift.async.AsyncMethodCallback;
import org.apache.thrift.async.TAsyncClientManager;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.transport.TNonblockingSocket;
import org.apache.thrift.transport.TNonblockingTransport;

import com.micmiu.thrift.demo.HelloWorldService.AsyncClient.sayHello_call;

/**
 * blog http://www.micmiu.com
 *
 * @author Michael
 *
 */
public class HelloAsynClientDemo {

	public static final String SERVER_IP = "localhost";
	public static final int SERVER_PORT = 8090;
	public static final int TIMEOUT = 30000;

	/**
	 *
	 * @param userName
	 */
	public void startClient(String userName) {
		try {
			TAsyncClientManager clientManager = new TAsyncClientManager();
			TNonblockingTransport transport = new TNonblockingSocket(SERVER_IP,
					SERVER_PORT, TIMEOUT);

			TProtocolFactory tprotocol = new TCompactProtocol.Factory();
			HelloWorldService.AsyncClient asyncClient = new HelloWorldService.AsyncClient(
					tprotocol, clientManager, transport);
			System.out.println("Client start .....");

			CountDownLatch latch = new CountDownLatch(1);
			AsynCallback callBack = new AsynCallback(latch);
			System.out.println("call method sayHello start ...");
			asyncClient.sayHello(userName, callBack);
			System.out.println("call method sayHello .... end");
			boolean wait = latch.await(30, TimeUnit.SECONDS);
			System.out.println("latch.await =:" + wait);
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("startClient end.");
	}

	public class AsynCallback implements AsyncMethodCallback<sayHello_call> {
		private CountDownLatch latch;

		public AsynCallback(CountDownLatch latch) {
			this.latch = latch;
		}

		@Override
		public void onComplete(sayHello_call response) {
			System.out.println("onComplete");
			try {
				// Thread.sleep(1000L * 1);
				System.out.println("AsynCall result =:"
						+ response.getResult().toString());
			} catch (TException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				latch.countDown();
			}
		}

		@Override
		public void onError(Exception exception) {
			System.out.println("onError :" + exception.getMessage());
			latch.countDown();
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		HelloAsynClientDemo client = new HelloAsynClientDemo();
		client.startClient("Michael");

	}

}

先运行服务程序,再运行客户端程序,测试结果如下:

Client start .....
call method sayHello start ...
call method sayHello .... end
onComplete
AsynCall result =:Hi,Michael welcome to my blog www.micmiu.com
latch.await =:true
startClient end.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的 Thrift Java 实例,展示了如何使用 Thrift 进行跨语言通信。 1. 编写 Thrift IDL 文件 定义一个 Thrift 接口,使用 Thrift IDL 语言编写一个服务接口文件,例如 Example.thrift: ``` namespace java com.example service ExampleService { string ping(1: string message) } ``` 2. 生成 Java 代码 使用 Thrift 编译器将 Thrift IDL 文件编译成 Java 代码: ``` thrift --gen java Example.thrift ``` 将会生成 Java 的代码文件,可以根据需要进行使用。 3. 实现服务端 使用生成的代码实现服务端,例如: ```java public class ExampleHandler implements ExampleService.Iface { @Override public String ping(String message) throws TException { return "Pong: " + message; } } public static void main(String[] args) throws Exception { TServerTransport serverTransport = new TServerSocket(9090); ExampleService.Processor<ExampleHandler> processor = new ExampleService.Processor<>(new ExampleHandler()); TServer server = new TSimpleServer(new TServer.Args(serverTransport).processor(processor)); System.out.println("Starting the server..."); server.serve(); } ``` 4. 实现客户端 使用生成的代码实现客户端,例如: ```java public static void main(String[] args) throws Exception { TTransport transport = new TSocket("localhost", 9090); transport.open(); TProtocol protocol = new TBinaryProtocol(transport); ExampleService.Client client = new ExampleService.Client(protocol); String response = client.ping("Hello, world!"); System.out.println(response); transport.close(); } ``` 以上就是一个简单的 Thrift Java 实例,展示了如何使用 Thrift 进行跨语言通信。使用 Thrift 进行跨语言通信的优点是语言无关性,可以方便地在不同的编程语言中实现服务端和客户端。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值