转载地址: http://www.micmiu.com/soa/rpc/thrift-sample/
thrift: 系统之间的数据的传输, 调用对外暴露的接口,然后获取封装的具体的业务数据结果。 一种比较灵活的RPC。
namespace java com.thrift.demo
service HelloWorldService {
string sayHello(1:string username)
}
1)安装thrift:到thrift官网下载exe文件,然后将文件重命名为thrift.exe,拷贝到c:\windows目录下(或者任何目录下),然后就可以在dos环境下使用了
c:\windows>thrift -gen java D:\mywork\javaProject\thriftTest\test.thrift ,输出的java文件默认输出到当前目录下c:\windows,也可以使用-o参数指定输出路径
创建上面的一个thrift文件, 使用命令生成HelloWorldService.java文件。
加载需要的包。
<dependencies>
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.8</version>
</dependency>
</dependencies>
实现接口,
package com.thrift.demo;
import org.apache.thrift.TException;
public class HelloWorldImpl implements HelloWorldService.Iface{
@Override
public String sayHello(String username) throws TException {
return "Hi," + username + " ,我是服务端实现类";
}
}
这个就是暴露给另外系统的接口, 里面也就是自己的业务逻辑代码处理。
服务类如下:
package com.test;
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.server.TSimpleServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.transport.TServerSocket;
import com.thrift.demo.HelloWorldImpl;
import com.thrift.demo.HelloWorldService;
public class HelloServerDemo {
public static void main(String[] args) {
HelloServerDemo serverDemo = new HelloServerDemo();
//serverDemo.startServer();
serverDemo.startAsyServer();
}
public void startServer(){
try{
HelloWorldService.Processor<HelloWorldService.Iface> tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(new HelloWorldImpl());
// 简单单线程服务模型 ,一般用于测试
TServerSocket serverTransport = new TServerSocket(8090);
TServer.Args tArgs = new TServer.Args(serverTransport);
tArgs.processor(tprocessor);
// TProtocol 协议要对的上。
tArgs.protocolFactory(new TCompactProtocol.Factory());
TServer server = new TSimpleServer(tArgs);
server.serve();
}catch(Exception e){
System.out.println("Server start error!!!");
e.printStackTrace();
}
}
/**
*
* @Title: startAsyServer
* @Description: TODO 异步客户端对应的服务端
* @param 设定文件
* @return void 返回类型
* @throws
*/
public void startAsyServer(){
try {
System.out.println("HelloWorld TNonblockingServer start ....");
TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(
new HelloWorldImpl());
TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(
8090);
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();
}
}
}
客户端:(单线程简单测试)
package com.test;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import com.thrift.demo.HelloWorldService;
/***
*
TBinaryProtocol : 二进制格式.
TCompactProtocol : 压缩格式
TJSONProtocol : JSON格式
TSimpleJSONProtocol : 提供JSON只写协议, 生成的文件很容易通过脚本语言解析
thrift生成代码
实现接口Iface
TSimpleServer服务模型
TThreadPoolServer 服务模型
TNonblockingServer 服务模型
THsHaServer服务模型
异步客户端
*
*/
public class HelloClientDemo {
public static void main(String[] args) {
try{
TTransport transport = new TSocket("127.0.0.1", 8090, 30000);
TProtocol protocol = new TCompactProtocol(transport);
HelloWorldService.Client client = new HelloWorldService.Client(
protocol);
transport.open();
String result = client.sayHello("小强");
System.out.println("Thrift client result =: " + result);
}catch(Exception e){
e.printStackTrace();
}
}
}
异步客户端:(对应的是服务端的startAsyServer这个方法)
package com.test;
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.thrift.demo.HelloWorldService;
import com.thrift.demo.HelloWorldService.AsyncClient.sayHello_call;
public class HelloAsynClientDemo {
public static final String SERVER_IP = "localhost";
public static final int SERVER_PORT = 8090;
public static final int TIMEOUT = 30000;
public static void main(String[] args) {
HelloAsynClientDemo client = new HelloAsynClientDemo();
client.startClient("Michael");
}
/**
*
* @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();
}
}
}
总体感觉, 这种形式的数据传输更加的简单和方便。