例如,我想开拓一个快速打算的RPC做事,它紧张通过接口函数getInt对外供应做事,这个RPC做事的getInt函数利用用户传入的参数,经由繁芜的打算,打算出一个整形值返回给用户;做事器端利用java措辞开拓,而调用客户端可以是java、c、python等措辞开拓的程序,在这种运用处景下,我们只须要利用Thrift的IDL描述一下getInt函数(以.thrift为后缀的文件),然后利用Thrift的多措辞编译功能,将这个IDL文件编译成C、java、python几种措辞对应的“特定措辞接口文件”(每种措辞只须要一条大略的命令即可编译完成),这样拿到对应措辞的“特定措辞接口文件”之后,就可以开拓客户端和做事器真个代码了,开拓过程中只要接口不变,客户端和做事器真个开拓可以独立的进行。
Thrift为做事器端程序供应了很多的事情模式,例如:线程池模型、非壅塞模型等等,可以根据自己的实际运用处景选择一种事情模式高效地对外供应做事;
Thrift是一个软件框架, 用来进行可扩展且跨措辞的做事的开拓. 它结合了功能强大的软件堆栈和代码天生引擎, 已构建在 C++, Java, Go,Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 这些编程措辞间无缝结合的、高效的做事.> 官网地址: thrift.apache.org

Thrift是一种接口描述措辞和二进制通讯协议,它被用来定义和创建跨措辞的做事。它被当作一个远程过程调用(RPC)框架来利用,是由Facebook为“大规模跨措辞做事开拓”而开拓的。它通过一个代码天生引擎联合了一个软件栈,来创建不同程度的、无缝的跨平台高效做事,可以利用C#、C++(基于POSIX兼容系统)、Cappuccino、Cocoa、Delphi、Erlang、Go、Haskell、Java、Node.js、OCaml、Perl、PHP、Python、Ruby和Smalltalk。虽然它以前是由Facebook开拓的,但它现在是Apache软件基金会的开源项目了。该实现被描述在2007年4月的一篇由Facebook揭橥的技能论文中,该论文现由Apache掌管。
QuickStarthttps://thrift.apache.org/
Getting Started
Download Apache ThriftTo get started, download a copy of Thrift.Build and Install the Apache Thrift compilerYou will then need to build the Apache Thrift compiler and install it. See the installing Thrift guide for any help with this step.Writing a .thrift file After the Thrift compiler is installed you will need to create a thrift file. This file is an interface definition made up of thrift types and Services. The services you define in this file are implemented by the server and are called by any clients. The Thrift compiler is used to generate your Thrift File into source code which is used by the different client libraries and the server you write. To generate the source from a thrift file runthrift --gen <language> <Thrift filename>The sample tutorial.thrift file used for all the client and server tutorials can be found here.To learn more about Apache Thrift Read the Whitepaper
Simple TutorialFirst things first, you'll need to install the Thrift compiler and the language libraries. Do that using the instructions in the top level README.md file.Read tutorial.thrift to learn about the syntax of a Thrift fileCompile the code for the language of your choice: $ thrift $ thrift -r --gen cpp tutorial.thrift
Take a look at the generated code. Look in the language directories for sample client/server code. That's about it for now. This tutorial is intentionally brief. It should be just enough to get you started and ready to build your own project.
https://github.com/apache/thrift/tree/master/tutorial
架构
Thrift包含一套完全的栈来创建客户端和做事端程序。顶层部分是由Thrift定义天生的代码。而做事则由这个文件客户端和处理器代码天生。在天生的代码里会创建不同于内建类型的数据构造,并将其作为结果发送。协议和传输层是运行韶光的一部分。有了Thrift,就可以定义一个做事或改变通讯和传输协议,而无需重新编译代码。除了客户端部分之外,Thrift还包括做事器根本举动步伐来集成协议和传输,如壅塞、非壅塞及多线程做事器。栈中作为I/O根本的部分对付不同的措辞则有不同的实现。
Thrift支持浩瀚通讯协议:
TBinaryProtocol – 一种大略的二进制格式,大略,但没有为空间效率而优化。比文本协议处理起来更快,但更难于调试。TCompactProtocol – 更紧凑的二进制格式,处理起来常日同样高效。TDebugProtocol – 一种人类可读的文本格式,用来帮忙调试。TDenseProtocol – 与TCompactProtocol类似,将传输数据的元信息剥离。TJSONProtocol – 利用JSON对数据编码。TSimpleJSONProtocol – 一种只写协议,它不能被Thrift解析,由于它利用JSON时丢弃了元数据。适宜用脚本措辞来解析。支持的传输协议有:
TFileTransport – 该传输协议会写文件。TFramedTransport – 当利用一个非壅塞做事器时,哀求利用这个传输协议。它按帧来发送数据,个中每一帧的开头是长度信息。TMemoryTransport – 利用存储器映射输入输出。(Java的实现利用了一个大略的ByteArrayOutputStream。)TSocket – 利用壅塞的套接字I/O来传输。TZlibTransport – 用zlib实行压缩。用于连接另一个传输协议。Thrift还供应浩瀚的做事器,包括:
TNonblockingServer – 一个多线程做事器,它利用非壅塞I/O(Java的实现利用了NIO通道)。TFramedTransport必须跟这个做事器配套利用。TSimpleServer – 一个单线程做事器,它利用标准的壅塞I/O。测试时很有用。TThreadPoolServer – 一个多线程做事器,它利用标准的壅塞I/O。优点Thrift一些已经明确的优点包括:
跟一些替代选择,比如SOAP比较,跨措辞序列化的代价更低,由于它利用二进制格式。它有一个又瘦又干净的库,没有编码框架,没有XML配置文件。绑定觉得很自然。例如,Java利用java.util.ArrayList<String>;C++利用std::vector<std::string>。运用层通讯格式与序列化层通讯格式是完备分离的。它们都可以独立修正。预定义的序列化格式包括:二进制格式、对HTTP友好的格式,以及紧凑的二进制格式。兼作跨措辞文件序列化。协议利用软版本号机制软件版本管理。Thrift不哀求一个中央化的和显式的版本号机制,例如主版本号/次版本号。松耦合的团队可以轻松地掌握RPC调用的演进。没有构建依赖也不含非标准化的软件。不存在不兼容的软件容许证混用的情形。创建一个Thrift做事Thrift由C++编写,但可以为浩瀚措辞创建代码。要创建一个Thrift做事,必须写一些Thrift文件来描述它,为目标措辞天生代码,并且写一些代码来启动做事器及从客户端调用它。
Thrift将由这个描述信息天生独立的代码。例如,在Java里,PhoneType将是Phone类中一个大略的enum。
安装Thrift 的安装比较大略, 在 Mac 下可以直策应用 brew 快速安装.
brewinstallthrift
Window 或 Linux 可以通过官网 下载, 这里就不再多说了.
当下载安装完毕后, 我们就会得到一个名为 thrift (Window 下是 thrift.exe) 的工具, 通过它就可以天生各个措辞的 thrift 代码.
根本数据类型Thrift 脚本可定义的数据类型包括以下几种类型:
基本类型bool: 布尔值, true 或 false, 对应 Java 的 booleanbyte: 8 位有符号整数, 对应 Java 的 bytei16: 16 位有符号整数, 对应 Java 的 shorti32: 32 位有符号整数, 对应 Java 的 inti64: 64 位有符号整数, 对应 Java 的 longdouble: 64 位浮点数, 对应 Java 的 doublestring: 未知编码文本或二进制字符串, 对应 Java 的 Stringstruct 类型定义公共的工具, 类似于 C 措辞中的构造体定义, 在 Java 中是一个 JavaBean
union 类型和 C/C++ 中的 union 类似.
容器类型:list: 对应 Java 的 ArrayListset: 对应 Java 的 HashSetmap: 对应 Java 的 HashMapexception 类型对应 Java 的 Exception
service 类型对应做事的类.
service 类型可以被继续, 例如:
service PeopleDirectory { oneway void log(1: string message), void reloadDatabase()}service EmployeeDirectory extends PeopleDirectory { Employee findEmployee(1: i32employee_id) throws (1: MyError error), bool createEmployee(1: Employee new_employee)}
把稳到, 在定义 PeopleDirectory 做事的 log 方法时, 我们利用到了 oneway 关键字, 这个关键字的浸染是见告 thrift, 我们不关心函数的返回值, 不须要等待函数实行完毕就可以直接返回.oneway 关键字常日用于润色无返回值(void)的函数, 但是它和直接的无返回值的函数还是有差异的, 例如上面的 log 函数和 reloadDatabase 函数, 当客户端通过 thrift 进行远程调用做事真个 log 函数时, 不须要等待做事真个 log 函数实行结束就可以直接返回; 但是当客户端调用 reloadDatabase 方法时, 虽然这个方法也是无返回值的, 但客户端必须要壅塞等待, 直到做事端关照客户端此调用已结束后, 客户真个远程调用才可以返回.
列举类型和 Java 中的 enum 类型一样, 例如:
enum Fruit { Apple, Banana,}
例子
下面是一个在 IDL 文件中利用各种类型的例子:
enum ResponseStatus { OK = 0, ERROR = 1,}struct ListResponse { 1: required ResponseStatus status, 2: optional list<i32> ids, 3: optional list<double> scores, 10: optional string strategy, 11: optional string globalId, 12: optional map<string, string> extraInfo,}service Hello { string helloString(1:string para) i32 helloInt(1:i32 para) bool helloBoolean(1:bool para) void helloVoid() string helloNull()}
关于 IDL 文件
所谓 IDL, 即 接口描述措辞, 在利用 thrift 前, 须要供应一个 .thrift 后缀的文件, 其内容是利用 IDL 描述的做事接口信息.例如如下的一个接口描述:
namespace java com.xys.thriftservice HelloWorldService { string sayHello(string name);}
这里我们定义了一个名为 HelloWorldService 的接口, 它有一个方法, 即 sayHello. 当通过 thrift --gen java test.thrift 来天生 thrift 接口做事时, 会产生一个 HelloWorldService.java 的文件, 在此文件中会定义一个 HelloWorldService.Iface 接口, 我们在做事器端实现此接口即可.
做事器端编码基本步骤实现做事处理接口 impl创建 Processor创建 Transport创建 Protocol创建 Server启动 Server例如:
public class HelloServer { public static final int SERVER_PORT = 8080; public static void main(String[] args) throws Exception { HelloServer server = new HelloServer(); server.startServer(); } public void startServer() throws Exception { // 创建 TProcessor TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(new HelloWorldImpl()); // 创建 TServerTransport, TServerSocket 继续于 TServerTransport TServerSocket serverTransport = new TServerSocket(SERVER_PORT); // 创建 TProtocol TProtocolFactory protocolFactory = new TBinaryProtocol.Factory(); TServer.Args tArgs = new TServer.Args(serverTransport); tArgs.processor(tprocessor); tArgs.protocolFactory(protocolFactory); // 创建 TServer TServer server = new TSimpleServer(tArgs); // 启动 Server server.serve(); }}
客户端编码基本步骤创建 Transport创建 Protocol基于 Potocol 创建 Client打开 Transport调用做事相应的方法.
public class HelloClient { public static final String SERVER_IP = "localhost"; public static final int SERVER_PORT = 8080; public static final int TIMEOUT = 30000; public static void main(String[] args) throws Exception { HelloClient client = new HelloClient(); client.startClient("XYS"); } public void startClient(String userName) throws Exception { // 创建 TTransport TTransport transport = new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT); // 创建 TProtocol TProtocol protocol = new TBinaryProtocol(transport); // 创建客户端. HelloWorldService.Client client = new HelloWorldService.Client(protocol); // 打开 TTransport transport.open(); // 调用做事方法 String result = client.sayHello(userName); System.out.println("Result: " + result); transport.close(); }}
Thrift 的网络栈
如上图所示, thrift 的网络栈包含了 transport 层, protocol 层, processor 层和 Server/Client 层.
Transport 层Transport 层供应了从网络中读取数据或将数据写入网络的抽象.Transport 层和 Protocol 层相互独立, 我们可以根据自己须要选择不同的 Transport 层, 而对上层的逻辑不造成任何影响.
Thrift 的 Java 实现中, 我们利用接口 TTransport 来描述传输层工具, 这个接供词给的常用方法有:
openclosereadwriteflush
而在做事器端, 我们常日会利用 TServerTransport 来监听客户真个要求, 并天生相对应的 Transport 工具, 这个接供词给的常用方法有:
openlistenacceptclose
为了利用上的方便, Thrift 供应了如下几个常用 Transport:
TSocket: 这个 transport 利用壅塞 socket 来收发数据.TFramedTransport: 以帧的形式发送数据, 每帧前面是一个长度. 当做事方利用 non-blocking IO 时(即做事器端利用的是 TNonblockingServerSocket), 那么就必须利用 TFramedTransport.TMemoryTransport: 利用内存 I/O. Java 实现中在内部利用了 ByteArrayOutputStreamTZlibTransport: 利用 Zlib 压缩传输的数据. 在 Java 中未实现.Protocol 层(数据传输协议层)这一层的浸染是内存中的数据构造转换为可通过 Transport 传输的数据流或者反操作, 即我们所谓的 序列化 和 反序列化.
常用的协议有:
TBinaryProtocol, 二进制格式TCompactProtocol, 压缩格式TJSONProtocol, JSON 格式TSimpleJSONProtocol, 供应 JSON 只写协议, 天生的文件很随意马虎通过脚本措辞解析.TDebugProtocoal, 利用人类可读的 Text 格式, 帮助调试把稳, 客户端和做事器的协议要一样.
Processor 层Processor 层工具由 Thrift 根据用户的 IDL 文件所天生, 我们常日不能随意指定.这一层紧张有两个功能:
从 Protocol 层读取数据, 然后转交给对应的 handler 处理将 handler 处理的构造发送 Prootcol 层.Server 层Thrift 供应的 Server 层实现有:
TNonblockingServer: 这个是一个基于多线程, 非壅塞 IO 的 Server 层实现, 它专门用于处理大量的并发要求的THsHaServer: 半同步/半异步做事器模型, 基于 TNonblockingServer 实现.TThreadPoolServer: 基于多线程, 壅塞 IO 的 Server 层实现, 它所花费的系统资源比 TNonblockingServer 高, 不过可以供应更高的吞吐量.TSimpleServer: 这个实现紧张是用于测试目的. 它只有一个线程, 并且是壅塞 IO, 因此在同一韶光只能处理一个连接.利用例子下面的例子在我的 Github 上有源码, 直接 clone 即可.
依赖<dependency> <groupId>org.apache.thrift</groupId> <artifactId>libthrift</artifactId> <version>0.10.0</version></dependency>
thrift 版本: 0.10.0把稳, jar 包的版本须要和 thrift 版本同等, 不然可能会有一些编译缺点
thrift 文件test.thrift
namespace java com.xys.thriftservice HelloWorldService { string sayHello(string name);}
编译
cd src/main/resources/thrift --gen java test.thriftmv gen-java/com/xys/thrift/HelloWorldService.java ../java/com/xys/thrift
当实行 thrift --gen java test.thrift 命令后, 会在当前目录下天生一个 gen-java 目录, 个中会以包路径格式存放着天生的做事器端 thrift 代码, 我们将其拷贝到工程对应的目录下即可.
做事实现public class HelloWorldImpl implements HelloWorldService.Iface { public HelloWorldImpl() { } @Override public String sayHello(String name) throws TException { return "Hello, " + name; }}
做事端/客户端实现
下面我们分别根据做事器真个几种不同类型, 来分别实现它们, 并比拟这些模型的异同点.
TSimpleServer 做事器模型TSimpleServer 是一个大略的做事器端模型, 它只有一个线程, 并且利用的是壅塞 IO 模型, 因此一样平常用于测试环境中.
做事器端实现public class SimpleHelloServer { public static final int SERVER_PORT = 8080; public static void main(String[] args) throws Exception { SimpleHelloServer server = new SimpleHelloServer(); server.startServer(); } public void startServer() throws Exception { TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>( new HelloWorldImpl()); TServerSocket serverTransport = new TServerSocket(SERVER_PORT); TSimpleServer.Args tArgs = new TSimpleServer.Args(serverTransport); tArgs.processor(tprocessor); tArgs.protocolFactory(new TBinaryProtocol.Factory()); TServer server = new TSimpleServer(tArgs); server.serve(); }}
我们在做事器真个代码中, 没有显示地指定 Transport 的类型, 这个是由于 TSimpleServer.Args 在布局时, 会指定一个默认的 TransportFactory, 当有新的客户端连接时, 就会天生一个 TSocket 的 Transport 实例. 由于这一点, 我们在客户端实现时, 也就须要指定客户真个 Transport 为 TSocket 才行.
客户端实现public class SimpleHelloClient { public static final String SERVER_IP = "localhost"; public static final int SERVER_PORT = 8080; public static final int TIMEOUT = 30000; public void startClient(String userName) throws Exception { TTransport transport = null; transport = new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT); // 协议要和做事端同等 TProtocol protocol = new TBinaryProtocol(transport); HelloWorldService.Client client = new HelloWorldService.Client( protocol); transport.open(); String result = client.sayHello(userName); System.out.println("Result: " + result); transport.close(); } public static void main(String[] args) throws Exception { SimpleHelloClient client = new SimpleHelloClient(); client.startClient("XYS"); }}
TThreadPoolServer 做事器模型
TThreadPoolServer 是一个基于线程池和传统的壅塞 IO 模型实现, 每个线程对应着一个连接.
做事器端实现public class ThreadPoolHelloServer { public static final int SERVER_PORT = 8080; public static void main(String[] args) throws Exception { ThreadPoolHelloServer server = new ThreadPoolHelloServer(); server.startServer(); } public void startServer() throws Exception { TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>( new HelloWorldImpl()); TServerSocket serverTransport = new TServerSocket(SERVER_PORT); TThreadPoolServer.Args tArgs = new TThreadPoolServer.Args(serverTransport); tArgs.processor(tprocessor); tArgs.protocolFactory(new TBinaryProtocol.Factory()); TServer server = new TThreadPoolServer(tArgs); server.serve(); }}
TThreadPoolServer 的做事器端实现和 TSimpleServer 的没有很大差异, 只不过是在对应的地方把 TSimpleServer 改为 TThreadPoolServer 即可.
同样地, 我们在 TThreadPoolServer 做事器真个代码中, 和 TSimpleServer 一样, 没有显示地指定 Transport 的类型, 这里的缘故原由和 TSimpleServer 的一样, 就不再赘述了.
客户端实现代码实现和 SimpleHelloClient 一样.
TNonblockingServer 做事器模型TNonblockingServer 是基于线程池的, 并且利用了 Java 供应的 NIO 机制实现非壅塞 IO, 这个模型可以并发处理大量的客户端连接.把稳, 当利用 TNonblockingServer 模型是, 做事器端和客户真个 Transport 层须要指定为 TFramedTransport 或 TFastFramedTransport.
做事器端实现public class NonblockingHelloServer { public static final int SERVER_PORT = 8080; public static void main(String[] args) throws Exception { NonblockingHelloServer server = new NonblockingHelloServer(); server.startServer(); } public void startServer() throws Exception { TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>( new HelloWorldImpl()); TNonblockingServerSocket serverTransport = new TNonblockingServerSocket(SERVER_PORT); TNonblockingServer.Args tArgs = new TNonblockingServer.Args(serverTransport); tArgs.processor(tprocessor); tArgs.protocolFactory(new TBinaryProtocol.Factory()); // 下面这个设置 TransportFactory 的语句可以去掉 tArgs.transportFactory(new TFramedTransport.Factory()); TServer server = new TNonblockingServer(tArgs); server.serve(); }}
前面我们提到, 在 TThreadPoolServer 和 TSimpleServer 的做事器端代码实现中, 我们并没有显示地为做事器端设置 Transport, 由于 TSimpleServer.Args 和 TThreadPoolServer.Args 设置了默认的 TransportFactory, 其最终生成的 Transport 是一个 TSocket 实例.
那么在 TNonblockingServer 中又会是若何的情形呢?通过查看代码我们可以创造, TNonblockingServer.Args 布局时, 会调用父类 AbstractNonblockingServerArgs 的布局器, 其源码如下:
public AbstractNonblockingServerArgs(TNonblockingServerTransport transport) { super(transport); this.transportFactory(new TFramedTransport.Factory());}
可以看到, TNonblockingServer.Args 也会设置一个默认的 TransportFactory, 它的类型是 TFramedTransport#Factory, 因此终极 TNonblockingServer 所利用的 Transport 实在是 TFramedTransport 类型的, 这也便是为什么客户端也必须利用 TFramedTransport(或TFastFramedTransport) 类型的 Transport 的缘故原由了.
剖析到这里, 回过分来看代码实现, 我们就创造实在代码中 tArgs.transportFactory(new TFramedTransport.Factory()) 这一句是多余的, 不过为了强调一下, 我还是保留了.
客户端实现public class NonblockingHelloClient { public static final String SERVER_IP = "localhost"; public static final int SERVER_PORT = 8080; public static final int TIMEOUT = 30000; public void startClient(String userName) throws Exception { TTransport transport = null; // 客户端利用 TFastFramedTransport 也是可以的. transport = new TFramedTransport(new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT)); // 协议要和做事端同等 TProtocol protocol = new TBinaryProtocol(transport); HelloWorldService.Client client = new HelloWorldService.Client( protocol); transport.open(); String result = client.sayHello(userName); System.out.println("Result: " + result); transport.close(); } public static void main(String[] args) throws Exception { NonblockingHelloClient client = new NonblockingHelloClient(); client.startClient("XYS"); }}
异步客户端实现
在 TNonblockingServer 做事器模型下, 除了使同步式的客户端调用办法, 我们还可以在客户端中利用异步调用的办法, 详细代码如下:
public class NonblockingAsyncHelloClient { public static final String SERVER_IP = "localhost"; public static final int SERVER_PORT = 8080; public static final int TIMEOUT = 30000; public void startClient(String userName) throws Exception { TAsyncClientManager clientManager = new TAsyncClientManager(); TNonblockingTransport transport = new TNonblockingSocket(SERVER_IP, SERVER_PORT, TIMEOUT); // 协议要和做事端同等 TProtocolFactory protocolFactory = new TBinaryProtocol.Factory(); HelloWorldService.AsyncClient client = new HelloWorldService.AsyncClient( protocolFactory, clientManager, transport); client.sayHello(userName, new AsyncHandler()); Thread.sleep(500); } class AsyncHandler implements AsyncMethodCallback<String> { @Override public void onComplete(String response) { System.out.println("Got result: " + response); } @Override public void onError(Exception exception) { System.out.println("Got error: " + exception.getMessage()); } } public static void main(String[] args) throws Exception { NonblockingAsyncHelloClient client = new NonblockingAsyncHelloClient(); client.startClient("XYS"); }}
可以看到, 利用异步的客户端调用办法实现起来就比较繁芜了. 和 NonblockingHelloClient 比拟, 我们可以看到有几点不同:
异步客户端中须要定义一个 TAsyncClientManager 实例, 而同步客户端模式下不须要.异步客户端 Transport 层利用的是 TNonblockingSocket, 而同步客户端利用的是 TFramedTransport异步客户真个 Procotol 层工具须要利用 TProtocolFactory 来天生, 而同步客户端须要用户手动天生.异步客户真个 Client 是 HelloWorldService.AsyncClient, 而同步客户的 Client 是 HelloWorldService.Client末了也是最关键的不同点, 异步客户端须要供应一个异步处理 Handler, 用于处理做事器的回答.我们再来看一下 AsyncHandler 这个类. 这个类是用于异步回调用的, 当我们正常收到了做事器的回应后, Thrift 就会自动回调我们的 onComplete 方法, 因此我们在这里就可以设置我们的后续处理逻辑.当 Thrift 远程调用做事器端涌现非常时(例如做事器未启动), 那么就会回调到 onError 方法, 我们在这个方法中就可以做相应的缺点处理.
THsHaServer 做事器模型即 Half-Sync/Half-Async, 半同步/半异步做事器模型, 底层的实现实在还是依赖于 TNonblockingServer, 因此它所须要的 Transport 也是 TFramedTransport.
做事器端实现public class HsHaHelloServer { public static final int SERVER_PORT = 8080; public static void main(String[] args) throws Exception { HsHaHelloServer server = new HsHaHelloServer(); server.startServer(); } public void startServer() throws Exception { TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>( new HelloWorldImpl()); TNonblockingServerSocket serverTransport = new TNonblockingServerSocket(SERVER_PORT); THsHaServer.Args tArgs = new THsHaServer.Args(serverTransport); tArgs.processor(tprocessor); tArgs.protocolFactory(new TBinaryProtocol.Factory()); TServer server = new THsHaServer(tArgs); server.serve(); }}
客户端实现
和 NonblockingHelloClient 同等.
参考Learning-Apache-Thrift: https://thrift.apache.org/Thrift入门及Java实例演示https://baike.baidu.com/item/thrift/3879058?fr=aladdin