Thrift学习笔记(原创)
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) ,
}
说明:
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();
}
}
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()));
}
}
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( true , true );
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();
}
}
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( true , true );
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 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( true , true );
// 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));
}
public Server( int _port) throws TTransportException{
this .port = _port;
Factory protoFactory = new TBinaryProtocol.Factory( true , true );
// 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!