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 推荐值得一看的文章: http://jnb.ociweb.com/jnb/jnbJun2009.html http://wiki.apache.org/thrift
http://thrift.apache.org/static/files/thrift-20070401.pdf
Thrift是一个服务端和客户端的架构体系,就是socket传输,Thrift 具有自己内部定义的传输协议规范(TProtocol)和传输数据标准(TTransports),通过IDL脚本对传输数据的数据结构(struct) 和传输数据的业务逻辑(service)根据不同的运行环境快速的构建相应的代码,并且通过自己内部的序列化机制对传输的数据进行简化和压缩提高高并发、 大型系统中数据交互的成本,下图描绘了Thrift的整体架构,分为6个部分:
1.你的业务逻辑实现(You Code)
2.客户端和服务端对应的Service
3.执行读写操作的计算结果
4.TProtocol
5.TTransports
6.底层I/O通信
Thrift对软件栈的定义非常的清晰, 使得各个组件能够松散的耦合, 针对不同的应用场景, 选择不同是方式去搭建服务.
评注: Transport: 传输层,定义数据传输方式,可以为TCP/IP传输,内存共享或者文件共享等 protocol: 协议层, 定义数据传输格式,可以为二进制或者XML等 Processor: 处理层, 这部分由定义的idl来生成, 封装了协议输入输出流, 并委托给用户实现的handler进行处理. Server: 服务层, 整合上述组件, 提供网络模型(单线程/多线程/事件驱动), 最终形成真正的服务.
* Base Types:基本类型
bool Boolean, one byte
byte Signed byte
i16 Signed 16-bit integer
i32 Signed 32-bit integer
i64 Signed 64-bit integer
double 64-bit floating point value
string String
binary Blob (byte array)
* Struct:结构体类型
* Container:容器类型,即List、Set、Map
map Map from one type to another
list Ordered list of one type
set Set of unique elements of one type
* Exception:异常类型
* Service: 定义对象的接口,和一系列方法
Thrift可以让你选择客户端与服务端之间传输通信协议的类别,在传输协议上总体上划分为文本(text)和二进制(binary)传输协议, 为节约带宽,提供传输效率,一般情况下使用二进制类型的传输协议为多数,但有时会还是会使用基于文本类型的协议,这需要根据项目/产品中的实际需求:
* TBinaryProtocol – 二进制编码格式进行数据传输。
* TCompactProtocol – 这种协议非常有效的,使用Variable-Length Quantity (VLQ) 编码对数据进行压缩。
* TJSONProtocol – 使用JSON的数据编码协议进行数据传输。
* TSimpleJSONProtocol – 这种节约只提供JSON只写的协议,适用于通过脚本语言解析
* TDebugProtocol – 在开发的过程中帮助开发人员调试用的,以文本的形式展现方便阅读。
* TSocket- 使用堵塞式I/O进行传输,也是最常见的模式。
* TFramedTransport- 使用非阻塞方式,按块的大小,进行传输,类似于Java中的NIO。
* TFileTransport- 顾名思义按照文件的方式进程传输,虽然这种方式不提供Java的实现,但是实现起来非常简单。
* TMemoryTransport- 使用内存I/O,就好比Java中的ByteArrayOutputStream实现。
* TZlibTransport- 使用执行zlib压缩,不提供Java的实现。
1). TServer类层次体系
TSimpleServer/TThreadPoolServer是阻塞服务模型
TNonblockingServer/THsHaServer/TThreadedSelectotServer是非阻塞服务模型(NIO)
2). TServer抽象类的定义
内部静态类Args的定义, 用于TServer类用于串联软件栈(传输层, 协议层, 处理层)
public abstract class TServer {
public static class Args extends AbstractServerArgs {
public Args(TServerTransport transport) {
super (transport);
}
}
public static abstract class AbstractServerArgsextends AbstractServerArgs> {
public AbstractServerArgs(TServerTransport transport);
public T processorFactory(TProcessorFactory factory);
public T processor(TProcessor processor);
public T transportFactory(TTransportFactory factory);
public T protocolFactory(TProtocolFactory factory);
}
}
TServer类定义的抽象类
public abstract class TServer {
public abstract void serve();
public void stop();
public boolean isServing();
public void setServerEventHandler(TServerEventHandler eventHandler);
}
评注:抽象函数serve由具体的TServer实例来实现, 而并非所有的服务都需要优雅的退出, 因此stop没有被定义为抽象。
各种服务模型介绍如下:
* TSimpleServer - 单线程服务器端使用标准的堵塞式I/O,只适合测试开发使用。抽象代码描述如下:
serverSocket.listen();
while ( isServing() ) {
client = serverSocket.accept();
processor = factory.getProcess(client);
while ( true ) {
if ( !processor.process(input, output) ) {
break ;
}
}
}
* TThreadPoolServer - 多线程服务器端使用标准的堵塞式I/O。引入了线程池,实现的模型是One Thread Per Connection。
线程池代码片段如下:
private static ExecutorService createDefaultExecutorService(Args args) {
SynchronousQueue executorQueue =
new SynchronousQueue();
return new ThreadPoolExecutor(args.minWorkerThreads,
args.maxWorkerThreads,
60 ,
TimeUnit.SECONDS,
executorQueue);
}
采用同步队列(SynchronousQueue), 线程池采用能线程数可伸缩的模式.
主线程循环:
setServing( true );
while (!stopped_) {
try {
TTransport client = serverTransport_.accept();
WorkerProcess wp = new WorkerProcess(client);
executorService_.execute(wp);
} catch (TTransportException ttx) {
}
}
拆分了监听线程(accept)和处理客户端连接的工作线程(worker), 监听线程每接到一个客户端, 就投给线程池去处理. 这种模型能提高并发度, 但并发数取决于线程数, IO依旧阻塞, 从而限制该服务的服务能力。
* TNonblockingServer – 采用NIO的模式, 借助Channel/Selector机制, 采用IO事件模型来处理。
private void select() {
try {
selector.select();
Iterator selectedKeys = selector.selectedKeys().iterator();
while (!stopped_ && selectedKeys.hasNext()) {
SelectionKey key = selectedKeys.next();
selectedKeys.remove();
if (key.isAcceptable()) {
handleAccept();
} else if (key.isReadable()) {
handleRead(key);
} else if (key.isWritable()) {
handleWrite(key);
}
}
} catch (IOException e) {
}
}
select代码里对accept/read/write等IO事件进行监控和处理, 唯一可惜的这个单线程处理. 当遇到handler里有阻塞的操作时, 会导致整个服务被阻塞住。
*THsHaServer - 半同步半异步
鉴于TNonblockingServer的缺点, THsHa引入了线程池去处理, 其模型把读写任务放到线程池去处理。HsHa是: Half-sync/Half-async的处理模式, Half-aysnc是在处理IO事件上(accept/read/write io), Half-sync用于handler对rpc的同步处理上.
*TThreadedSelectorServer- 多线程服务器端使用非堵塞式I/O,是对以上NonblockingServer的扩充, 其分离了Accept和Read/Write的Selector线程, 同时引入Worker工作线程池. 它也是种Half-sync/Half-async的服务模型,也是最成熟,也是被业界所推崇的RPC服务模型。
MainReactor就是Accept线程, 用于监听客户端连接, SubReactor采用IO事件线程(多个), 主要负责对所有客户端的IO读写事件进行处理. 而Worker工作线程主要用于处理每个rpc请求的handler回调处理(这部分是同步的)。
1.定义接口描述
创建Thrift文件HelloWorld.thrift,定义接口描述:
namespace java cn.slimsmart.thrift.demo.helloworld
service HelloWorld{
string sayHello(1:string username)
}
2.生成java接口文件
使用thrift.exe工具生成java接口文件,下载thrift-0.9.2.exe工具
thrift-0.9.2.exe -r -gen java ./HelloWorld .thrift
package cn.slimsmart.thrift.demo.helloworld;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collections;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Generated;
import org.apache.thrift.TException;
import org.apache.thrift.async.AsyncMethodCallback;
import org.apache.thrift.protocol.TTupleProtocol;
import org.apache.thrift.scheme.IScheme;
import org.apache.thrift.scheme.SchemeFactory;
import org.apache.thrift.scheme.StandardScheme;
import org.apache.thrift.scheme.TupleScheme;
import org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings ({ "cast" , "rawtypes" , "serial" , "unchecked" })
@Generated (value = "Autogenerated by Thrift Compiler (0.9.2)" , date = "2015-2-28" )
public class HelloWorld {
public interface Iface {
public String sayHello(String username) throws org.apache.thrift.TException;
}
public interface AsyncIface {
public void sayHello(String username, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
}
public static class Client extends org.apache.thrift.TServiceClient implements Iface {
public static class Factory implements org.apache.thrift.TServiceClientFactory {
public Factory() {}
public Client getClient(org.apache.thrift.protocol.TProtocol prot) {
return new Client(prot);
}
public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
return new Client(iprot, oprot);
}
}
public Client(org.apache.thrift.protocol.TProtocol prot)
{
super (prot, prot);
}
public Client(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
super (iprot, oprot);
}
public String sayHello(String username) throws org.apache.thrift.TException
{
send_sayHello(username);
return recv_sayHello();
}
public void send_sayHello(String username) throws org.apache.thrift.TException
{
sayHello_args args = new sayHello_args();
args.setUsername(username);
sendBase("sayHello" , args);
}
public String recv_sayHello() throws org.apache.thrift.TException
{
sayHello_result result = new sayHello_result();
receiveBase(result, "sayHello" );
if (result.isSetSuccess()) {
return result.success;
}
throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "sayHello failed: unknown result" );
}
}
public static class AsyncClient extends org.apache.thrift.async.TAsyncClient implements AsyncIface {
public static class Factory implements org.apache.thrift.async.TAsyncClientFactory {
private org.apache.thrift.async.TAsyncClientManager clientManager;
private org.apache.thrift.protocol.TProtocolFactory protocolFactory;
public Factory(org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.protocol.TProtocolFactory protocolFactory) {
this .clientManager = clientManager;
this .protocolFactory = protocolFactory;
}
public AsyncClient getAsyncClient(org.apache.thrift.transport.TNonblockingTransport transport) {
return new AsyncClient(protocolFactory, clientManager, transport);
}
}
public AsyncClient(org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.transport.TNonblockingTransport transport) {
super (protocolFactory, clientManager, transport);
}
public void sayHello(String username, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
checkReady();
sayHello_call method_call = new sayHello_call(username, resultHandler, this , ___protocolFactory, ___transport);
this .___currentMethod = method_call;
___manager.call(method_call);
}
public static class sayHello_call extends org.apache.thrift.async.TAsyncMethodCall {
private String username;
public sayHello_call(String username, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
super (client, protocolFactory, transport, resultHandler, false );
this .username = username;
}
public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage( "sayHello" , org.apache.thrift.protocol.TMessageType.CALL, 0 ));
sayHello_args args = new sayHello_args();
args.setUsername(username);
args.write(prot);
prot.writeMessageEnd();
}
public String getResult() throws org.apache.thrift.TException {
if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
throw new IllegalStateException( "Method call not finished!" );
}
org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
return ( new Client(prot)).recv_sayHello();
}
}
}
public static class Processorextends Iface> extends org.apache.thrift.TBaseProcessor implements org.apache.thrift.TProcessor {
public Processor(I iface) {
super (iface, getProcessMap( new HashMapextends org.apache.thrift.TBase>>()));
}
protected Processor(I iface, Mapextends org.apache.thrift.TBase>> processMap) {
super (iface, getProcessMap(processMap));
}
private static extends Iface> Mapextends org.apache.thrift.TBase>> getProcessMap(Mapextends org.apache.thrift.TBase>> processMap) {
processMap.put("sayHello" , new sayHello());
return processMap;
}
public static class sayHelloextends Iface> extends org.apache.thrift.ProcessFunction {
public sayHello() {
super ( "sayHello" );
}
public sayHello_args getEmptyArgsInstance() {
return new sayHello_args();
}
protected boolean isOneway() {
return false ;
}
public sayHello_result getResult(I iface, sayHello_args args) throws org.apache.thrift.TException {
sayHello_result result = new sayHello_result();
result.success = iface.sayHello(args.username);
return result;
}
}
}
public static class AsyncProcessorextends AsyncIface> extends org.apache.thrift.TBaseAsyncProcessor {
private static final Logger LOGGER = LoggerFactory.getLogger(AsyncProcessor. class .getName());
public AsyncProcessor(I iface) {
super (iface, getProcessMap( new HashMapextends org.apache.thrift.TBase, ?>>()));
}
protected AsyncProcessor(I iface, Mapextends org.apache.thrift.TBase, ?>> processMap) {
super (iface, getProcessMap(processMap));
}
private static extends AsyncIface> Mapextends org.apache.thrift.TBase,?>> getProcessMap(Mapextends org.apache.thrift.TBase, ?>> processMap) {
processMap.put("sayHello" , new sayHello());
return processMap;
}
public static class sayHelloextends AsyncIface> extends org.apache.thrift.AsyncProcessFunction {
public sayHello() {
super ( "sayHello" );
}
public sayHello_args getEmptyArgsInstance() {
return new sayHello_args();
}
public AsyncMethodCallback getResultHandler( final AsyncFrameBuffer fb, final int seqid) {
final org.apache.thrift.AsyncProcessFunction fcall = this ;
return new AsyncMethodCallback() {
public void onComplete(String o) {
sayHello_result result = new sayHello_result();
result.success = o;
try {
fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
return ;
} catch (Exception e) {
LOGGER.error("Exception writing to internal frame buffer" , e);
}
fb.close();
}
public void onError(Exception e) {
byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
org.apache.thrift.TBase msg;
{
msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
}
try {
fcall.sendResponse(fb,msg,msgType,seqid);
return ;
} catch (Exception ex) {
LOGGER.error("Exception writing to internal frame buffer" , ex);
}
fb.close();
}
};
}
protected boolean isOneway() {
return false ;
}
public void start(I iface, sayHello_args args, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws TException {
iface.sayHello(args.username,resultHandler);
}
}
}
public static class sayHello_args implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable {
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct( "sayHello_args" );
private static final org.apache.thrift.protocol.TField USERNAME_FIELD_DESC = new org.apache.thrift.protocol.TField( "username" , org.apache.thrift.protocol.TType.STRING, ( short ) 1 );
private static final Mapextends IScheme>, SchemeFactory> schemes = new HashMapextends IScheme>, SchemeFactory>();
static {
schemes.put(StandardScheme.class , new sayHello_argsStandardSchemeFactory());
schemes.put(TupleScheme.class , new sayHello_argsTupleSchemeFactory());
}
public String username;
public enum _Fields implements org.apache.thrift.TFieldIdEnum {
USERNAME((short ) 1 , "username" );
private static final Map byName = new HashMap();
static {
for (_Fields field : EnumSet.allOf(_Fields. class )) {
byName.put(field.getFieldName(), field);
}
}
public static _Fields findByThriftId( int fieldId) {
switch (fieldId) {
case 1 :
return USERNAME;
default :
return null ;
}
}
public static _Fields findByThriftIdOrThrow( int fieldId) {
_Fields fields = findByThriftId(fieldId);
if (fields == null ) throw new IllegalArgumentException( "Field " + fieldId + " doesn't exist!" );
return fields;
}
public static _Fields findByName(String name) {
return byName.get(name);
}
private final short _thriftId;
private final String _fieldName;
_Fields(short thriftId, String fieldName) {
_thriftId = thriftId;
_fieldName = fieldName;
}
public short getThriftFieldId() {
return _thriftId;
}
public String getFieldName() {
return _fieldName;
}
}
public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
static {
Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields. class );
tmpMap.put(_Fields.USERNAME, new org.apache.thrift.meta_data.FieldMetaData( "username" , org.apache.thrift.TFieldRequirementType.DEFAULT,
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
metaDataMap = Collections.unmodifiableMap(tmpMap);
org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(sayHello_args.class , metaDataMap);
}
public sayHello_args() {
}
public sayHello_args(
String username)
{
this ();
this .username = username;
}
public sayHello_args(sayHello_args other) {
if (other.isSetUsername()) {
this .username = other.username;
}
}
public sayHello_args deepCopy() {
return new sayHello_args( this );
}
@Override
public void clear() {
this .username = null ;
}
public String getUsername() {
return this .username;
}
public sayHello_args setUsername(String username) {
this .username = username;
return this ;
}
public void unsetUsername() {
this .username = null ;
}
public boolean isSetUsername() {
return this .username != null ;
}
public void setUsernameIsSet( boolean value) {
if (!value) {
this .username = null ;
}
}
public void setFieldValue(_Fields field, Object value) {
switch (field) {
case USERNAME:
if (value == null ) {
unsetUsername();
} else {
setUsername((String)value);
}
break ;
}
}
public Object getFieldValue(_Fields field) {
switch (field) {
case USERNAME:
return getUsername();
}
throw new IllegalStateException();
}
public boolean isSet(_Fields field) {
if (field == null ) {
throw new IllegalArgumentException();
}
switch (field) {
case USERNAME:
return isSetUsername();
}
throw new IllegalStateException();
}
@Override
public boolean equals(Object that) {
if (that == null )
return false ;
if (that instanceof sayHello_args)
return this .equals((sayHello_args)that);
return false ;
}
public boolean equals(sayHello_args that) {
if (that == null )
return false ;
boolean this_present_username = true && this .isSetUsername();
boolean that_present_username = true && that.isSetUsername();
if (this_present_username || that_present_username) {
if (!(this_present_username && that_present_username))
return false ;
if (! this .username.equals(that.username))
return false ;
}
return true ;
}
@Override
public int hashCode() {
List list = new ArrayList();
boolean present_username = true && (isSetUsername());
list.add(present_username);
if (present_username)
list.add(username);
return list.hashCode();
}
@Override
public int compareTo(sayHello_args other) {
if (!getClass().equals(other.getClass())) {
return getClass().getName().compareTo(other.getClass().getName());
}
int lastComparison = 0 ;
lastComparison = Boolean.valueOf(isSetUsername()).compareTo(other.isSetUsername());
if (lastComparison != 0 ) {
return lastComparison;
}
if (isSetUsername()) {
lastComparison = org.apache.thrift.TBaseHelper.compareTo(this .username, other.username);
if (lastComparison != 0 ) {
return lastComparison;
}
}
return 0 ;
}
public _Fields fieldForId( int fieldId) {
return _Fields.findByThriftId(fieldId);
}
public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
schemes.get(iprot.getScheme()).getScheme().read(iprot, this );
}
public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
schemes.get(oprot.getScheme()).getScheme().write(oprot, this );
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder( "sayHello_args(" );
sb.append("username:" );
if ( this .username == null ) {
sb.append("null" );
} else {
sb.append(this .username);
}
sb.append(")" );
return sb.toString();
}
public void validate() throws org.apache.thrift.TException {
}
private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
try {
write(new org.apache.thrift.protocol.TCompactProtocol( new org.apache.thrift.transport.TIOStreamTransport(out)));
} catch (org.apache.thrift.TException te) {
throw new java.io.IOException(te);
}
}
private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
try {
read(new org.apache.thrift.protocol.TCompactProtocol( new org.apache.thrift.transport.TIOStreamTransport(in)));
} catch (org.apache.thrift.TException te) {
throw new java.io.IOException(te);
}
}
private static class sayHello_argsStandardSchemeFactory implements SchemeFactory {
public sayHello_argsStandardScheme getScheme() {
return new sayHello_argsStandardScheme();
}
}
private static class sayHello_argsStandardScheme extends StandardScheme {
public void read(org.apache.thrift.protocol.TProtocol iprot, sayHello_args struct) throws org.apache.thrift.TException {
org.apache.thrift.protocol.TField schemeField;
iprot.readStructBegin();
while ( true )
{
schemeField = iprot.readFieldBegin();
if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
break ;
}
switch (schemeField.id) {
case 1 :
if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
struct.username = iprot.readString();
struct.setUsernameIsSet(true );
} else {
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
break ;
default :
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
iprot.readFieldEnd();
}
iprot.readStructEnd();
struct.validate();
}
public void write(org.apache.thrift.protocol.TProtocol oprot, sayHello_args struct) throws org.apache.thrift.TException {
struct.validate();
oprot.writeStructBegin(STRUCT_DESC);
if (struct.username != null ) {
oprot.writeFieldBegin(USERNAME_FIELD_DESC);
oprot.writeString(struct.username);
oprot.writeFieldEnd();
}
oprot.writeFieldStop();
oprot.writeStructEnd();
}
}
private static class sayHello_argsTupleSchemeFactory implements SchemeFactory {
public sayHello_argsTupleScheme getScheme() {
return new sayHello_argsTupleScheme();
}
}
private static class sayHello_argsTupleScheme extends TupleScheme {
@Override
public void write(org.apache.thrift.protocol.TProtocol prot, sayHello_args struct) throws org.apache.thrift.TException {
TTupleProtocol oprot = (TTupleProtocol) prot;
BitSet optionals = new BitSet();
if (struct.isSetUsername()) {
optionals.set(0 );
}
oprot.writeBitSet(optionals, 1 );
if (struct.isSetUsername()) {
oprot.writeString(struct.username);
}
}
@Override
public void read(org.apache.thrift.protocol.TProtocol prot, sayHello_args struct) throws org.apache.thrift.TException {
TTupleProtocol iprot = (TTupleProtocol) prot;
BitSet incoming = iprot.readBitSet(1 );
if (incoming.get( 0 )) {
struct.username = iprot.readString();
struct.setUsernameIsSet(true );
}
}
}
}
public static class sayHello_result implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable {
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct( "sayHello_result" );
private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField( "success" , org.apache.thrift.protocol.TType.STRING, ( short ) 0 );
private static final Mapextends IScheme>, SchemeFactory> schemes = new HashMapextends IScheme>, SchemeFactory>();
static {
schemes.put(StandardScheme.class , new sayHello_resultStandardSchemeFactory());
schemes.put(TupleScheme.class , new sayHello_resultTupleSchemeFactory());
}
public String success;
public enum _Fields implements org.apache.thrift.TFieldIdEnum {
SUCCESS((short ) 0 , "success" );
private static final Map byName = new HashMap();
static {
for (_Fields field : EnumSet.allOf(_Fields. class )) {
byName.put(field.getFieldName(), field);
}
}
public static _Fields findByThriftId( int fieldId) {
switch (fieldId) {
case 0 :
return SUCCESS;
default :
return null ;
}
}
public static _Fields findByThriftIdOrThrow( int fieldId) {
_Fields fields = findByThriftId(fieldId);
if (fields == null ) throw new IllegalArgumentException( "Field " + fieldId + " doesn't exist!" );
return fields;
}
public static _Fields findByName(String name) {
return byName.get(name);
}
private final short _thriftId;
private final String _fieldName;
_Fields(short thriftId, String fieldName) {
_thriftId = thriftId;
_fieldName = fieldName;
}
public short getThriftFieldId() {
return _thriftId;
}
public String getFieldName() {
return _fieldName;
}
}
public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
static {
Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields. class );
tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData( "success" , org.apache.thrift.TFieldRequirementType.DEFAULT,
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
metaDataMap = Collections.unmodifiableMap(tmpMap);
org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(sayHello_result.class , metaDataMap);
}
public sayHello_result() {
}
public sayHello_result(
String success)
{
this ();
this .success = success;
}
public sayHello_result(sayHello_result other) {
if (other.isSetSuccess()) {
this .success = other.success;
}
}
public sayHello_result deepCopy() {
return new sayHello_result( this );
}
@Override
public void clear() {
this .success = null ;
}
public String getSuccess() {
return this .success;
}
public sayHello_result setSuccess(String success) {
this .success = success;
return this ;
}
public void unsetSuccess() {
this .success = null ;
}
public boolean isSetSuccess() {
return this .success != null ;
}
public void setSuccessIsSet( boolean value) {
if (!value) {
this .success = null ;
}
}
public void setFieldValue(_Fields field, Object value) {
switch (field) {
case SUCCESS:
if (value == null ) {
unsetSuccess();
} else {
setSuccess((String)value);
}
break ;
}
}
public Object getFieldValue(_Fields field) {
switch (field) {
case SUCCESS:
return getSuccess();
}
throw new IllegalStateException();
}
public boolean isSet(_Fields field) {
if (field == null ) {
throw new IllegalArgumentException();
}
switch (field) {
case SUCCESS:
return isSetSuccess();
}
throw new IllegalStateException();
}
@Override
public boolean equals(Object that) {
if (that == null )
return false ;
if (that instanceof sayHello_result)
return this .equals((sayHello_result)that);
return false ;
}
public boolean equals(sayHello_result that) {
if (that == null )
return false ;
boolean this_present_success = true && this .isSetSuccess();
boolean that_present_success = true && that.isSetSuccess();
if (this_present_success || that_present_success) {
if (!(this_present_success && that_present_success))
return false ;
if (! this .success.equals(that.success))
return false ;
}
return true ;
}
@Override
public int hashCode() {
List list = new ArrayList();
boolean present_success = true && (isSetSuccess());
list.add(present_success);
if (present_success)
list.add(success);
return list.hashCode();
}
@Override
public int compareTo(sayHello_result other) {
if (!getClass().equals(other.getClass())) {
return getClass().getName().compareTo(other.getClass().getName());
}
int lastComparison = 0 ;
lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
if (lastComparison != 0 ) {
return lastComparison;
}
if (isSetSuccess()) {
lastComparison = org.apache.thrift.TBaseHelper.compareTo(this .success, other.success);
if (lastComparison != 0 ) {
return lastComparison;
}
}
return 0 ;
}
public _Fields fieldForId( int fieldId) {
return _Fields.findByThriftId(fieldId);
}
public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
schemes.get(iprot.getScheme()).getScheme().read(iprot, this );
}
public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
schemes.get(oprot.getScheme()).getScheme().write(oprot, this );
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder( "sayHello_result(" );
sb.append("success:" );
if ( this .success == null ) {
sb.append("null" );
} else {
sb.append(this .success);
}
sb.append(")" );
return sb.toString();
}
public void validate() throws org.apache.thrift.TException {
}
private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
try {
write(new org.apache.thrift.protocol.TCompactProtocol( new org.apache.thrift.transport.TIOStreamTransport(out)));
} catch (org.apache.thrift.TException te) {
throw new java.io.IOException(te);
}
}
private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
try {
read(new org.apache.thrift.protocol.TCompactProtocol( new org.apache.thrift.transport.TIOStreamTransport(in)));
} catch (org.apache.thrift.TException te) {
throw new java.io.IOException(te);
}
}
private static class sayHello_resultStandardSchemeFactory implements SchemeFactory {
public sayHello_resultStandardScheme getScheme() {
return new sayHello_resultStandardScheme();
}
}
private static class sayHello_resultStandardScheme extends StandardScheme {
public void read(org.apache.thrift.protocol.TProtocol iprot, sayHello_result struct) throws org.apache.thrift.TException {
org.apache.thrift.protocol.TField schemeField;
iprot.readStructBegin();
while ( true )
{
schemeField = iprot.readFieldBegin();
if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
break ;
}
switch (schemeField.id) {
case 0 :
if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
struct.success = iprot.readString();
struct.setSuccessIsSet(true );
} else {
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
break ;
default :
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
iprot.readFieldEnd();
}
iprot.readStructEnd();
struct.validate();
}
public void write(org.apache.thrift.protocol.TProtocol oprot, sayHello_result struct) throws org.apache.thrift.TException {
struct.validate();
oprot.writeStructBegin(STRUCT_DESC);
if (struct.success != null ) {
oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
oprot.writeString(struct.success);
oprot.writeFieldEnd();
}
oprot.writeFieldStop();
oprot.writeStructEnd();
}
}
private static class sayHello_resultTupleSchemeFactory implements SchemeFactory {
public sayHello_resultTupleScheme getScheme() {
return new sayHello_resultTupleScheme();
}
}
private static class sayHello_resultTupleScheme extends TupleScheme {
@Override
public void write(org.apache.thrift.protocol.TProtocol prot, sayHello_result struct) throws org.apache.thrift.TException {
TTupleProtocol oprot = (TTupleProtocol) prot;
BitSet optionals = new BitSet();
if (struct.isSetSuccess()) {
optionals.set(0 );
}
oprot.writeBitSet(optionals, 1 );
if (struct.isSetSuccess()) {
oprot.writeString(struct.success);
}
}
@Override
public void read(org.apache.thrift.protocol.TProtocol prot, sayHello_result struct) throws org.apache.thrift.TException {
TTupleProtocol iprot = (TTupleProtocol) prot;
BitSet incoming = iprot.readBitSet(1 );
if (incoming.get( 0 )) {
struct.success = iprot.readString();
struct.setSuccessIsSet(true );
}
}
}
}
}
将生成的接口
HelloWorld.java
复制到java工程下.
在pom.xml导入依赖jar包:
< dependency >
< groupId > org.apache.thrift groupId >
< artifactId > libthrift artifactId >
< version > 0.9.2 version >
dependency >
< dependency >
< groupId > org.slf4j groupId >
< artifactId > slf4j-log4j12 artifactId >
< version > 1.5.8 version >
dependency >
3.接口实现类
接口实现类HelloWorldImpl.java:
package cn.slimsmart.thrift.demo.helloworld;
import org.apache.thrift.TException;
public class HelloWorldImpl implements HelloWorld.Iface{
@Override
public String sayHello(String username) throws TException {
return "hello world, " +username;
}
}
4.服务器端
服务端启动类HelloTSimpleServer.java:
package cn.slimsmart.thrift.demo.helloworld;
import org.apache.thrift.TException;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;
public class HelloTSimpleServer {
public static final int SERVER_PORT = 8080 ;
public static void main(String[] args) throws TException {
TProcessor tprocessor = new HelloWorld.Processor( new HelloWorldImpl());
TServerSocket serverTransport = new TServerSocket(SERVER_PORT);
TServer.Args tArgs = new TServer.Args(serverTransport);
tArgs.processor(tprocessor);
tArgs.protocolFactory(new TBinaryProtocol.Factory());
TServer server = new TSimpleServer(tArgs);
System.out.println("HelloServer start...." );
server.serve();
}
}
5.客户端
客户端调用类HelloClient.java:
package cn.slimsmart.thrift.demo.helloworld;
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.TTransport;
public class HelloClient {
public static final String SERVER_IP = "127.0.0.1" ;
public static final int SERVER_PORT = 8080 ;
public static final int TIMEOUT = 30000 ;
public static void main(String[] args) throws TException {
TTransport transport = new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT);
TProtocol protocol = new TBinaryProtocol(transport);
HelloWorld.Client client = new HelloWorld.Client(protocol);
transport.open();
String result = client.sayHello("jack" );
System.out.println("result : " + result);
transport.close();
}
}
先运行服务端,再运行客户端,看一下运行结果吧。