Thrift 不僅是高效序列化工具,更是完整的跨語言 RPC 框架。本文通過一個「服務端主動推送響應」的雙向通信 Demo,完整演示 IDL 定義、代碼生成、Server/Client 實現與運行驗證。
student.thriftnamespace java com.zhj.student
typedef i32 int
struct Student { 1: string name }
service Zthrift {
oneway void send(1: Student msg) // oneway: 僅發送,不等待響應
}
oneway 關鍵字讓客戶端發送後立即返回,為雙向通信騰出連接通道。
thrift --gen java student.thrift
# 生成 gen-java/com/zhj/student/Student.java、Zthrift.java
public class ZServer {
public static void main(String[] args) throws TTransportException {
TServerSocket socket = new TServerSocket(9999);
TThreadPoolServer.Args sArgs = new TThreadPoolServer.Args(socket)
.protocolFactory(new TBinaryProtocol.Factory())
.processorFactory(new TProcessorFactory() {
@Override
public TProcessor getProcessor(TTransport trans) {
// 異步線程:5 秒後主動推送響應
new Thread(() -> {
try { Thread.sleep(5000);
Zthrift.Client client = new Zthrift.Client(new TBinaryProtocol(trans));
client.send(new Student("server-push-response"));
} catch (Exception e) { e.printStackTrace(); }
}).start();
// 同步處理接收請求
return new Zthrift.Processor<>(new Zthrift.Iface() {
@Override public void send(Student msg) {
System.out.println("收到客戶端: " + msg.name);
}
});
}
});
new TThreadPoolServer(sArgs).serve();
}
}
public class ZClient {
public static void main(String[] args) throws Exception {
TSocket socket = new TSocket("127.0.0.1", 9999);
TTransport transport = new TFramedTransport(socket);
transport.open();
Zthrift.Client client = new Zthrift.Client(new TBinaryProtocol(transport));
// 發送請求
client.send(new Student("client-request"));
// 阻塞循環接收服務端推送
Zthrift.Processor processor = new Zthrift.Processor<>(new Zthrift.Iface() {
@Override public void send(Student msg) {
System.out.println("收到服務端推送: " + msg.name);
}
});
while (processor.process(new TBinaryProtocol(transport), new TBinaryProtocol(transport))) {
// 保持連接處理雙向消息
}
}
}
start server...關鍵點:TFramedTransport 以幀為單位傳輸,TThreadPoolServer 線程池隔離業務邏輯,Processor.process() 循環實現雙向消息泵。