目錄
1、Thrift基礎
1.1 數據類型
基本類型:
- bool:布爾值,true 或 false,對應 C++ 的 bool
- byte:8 位有符號整數,對應 C++ 的 byte
- i16:16 位有符號整數,對應 C++ 的 short
- i32:32 位有符號整數,對應 C++ 的 int
- i64:64 位有符號整數,對應 C++ 的 long
- double:64 位浮點數,對應 C++ 的 double
- string:utf-8編碼的字符串,對應 C++ 的 string
結構體類型:
- struct:定義公共的對象,類似於 C 語言中的結構體定義
容器類型:
- list:對應 C++ 的 list
- set:對應 C++ 的 set
- map:對應 C++ 的map
異常類型:
- exception:對應 C++ 的 Exception
服務類型:
- service:對應服務的類
1.2 通訊支持
支持的數據傳輸協議(傳輸格式)
- TBinaryProtocol : 二進制格式.
- TCompactProtocol : 壓縮格式
- TJSONProtocol : JSON格式
- TSimpleJSONProtocol : 提供JSON只寫協議, 生成的文件很容易通過腳本語言解析
- tips: 客戶端和服務端的協議要一致
支持的數據傳輸方式
- TSocket -阻塞式socker
- TFramedTransport–以frame爲單位進行傳輸,非阻塞式服務中使用。
- TFileTransport – 以文件形式進行傳輸。
- TMemoryTransport –將內存用於I/O. java實現時使用了簡單的ByteArrayOutputStream。
- TZlibTransport – 使用zlib進行壓縮, 與其他傳輸方式聯合使用。當前無java實現。
支持的服務模型
- TSimpleServer – 簡單的單線程服務模型,常用於測試教學使用
- TThreadPoolServer – 多線程服務模型,使用標準的阻塞式IO。
- TNonblockingServer – 多線程服務模型,使用非阻塞式IO(需使用TFramedTransport數據傳輸方式)
2、Linux環境安裝Thrift
(1)安裝依賴項:
sudo apt-get install libboost-dev libboost-test-dev libboost-program-options-dev libevent-dev automake libtool flex bison pkg-config g++ libssl-dev
(2)將thrift安裝包下載下來,並解壓安裝
tar -zxvf thrift-0.13.0.tar.gz
cd thrift-0.13.0/
./configure
sudo make
sudo make install
(3)測試安裝是否成功
thrift -version
3、編寫c++測試用例
例子描述:我們將學生信息(學號,姓名,性別,年齡)由客戶端發送到服務端。
3.1 編寫thrift文件
學生信息使用thrift的struct即可,爲了達到通信目的,我們需要寫一個service。注意改出service的名字爲Serv,方法名字爲put。
student.thrift文件內容如下:
struct Student{
1: i32 sno,
2: string sname,
3: bool ssex,
4: i16 sage,
}
service Serv{
void put(1: Student s),
}
3.2 生成cpp文件
thrift可以簡易生成不同語言的代碼,c++ python java等,此處我們只用--gen cpp第一個命令即可
thrift -r --gen cpp student.thrift
#thrift -r --gen java student.thrift //生成java代碼
#thrift -r --gen py student.thrift //生成python代碼
如下生成7個文件:Serv開頭的文件是由service的名字生成的,查看Serv_server.skeleton.cpp可以看到put方法。這些文件可以編譯,生成最初的客戶端,編譯命令如下:
cd到gen-cpp所在的文件夾,執行如下編譯命令,注意生成的server可執行文件是在gen-cpp文件夾中的。
Serv.cpp
Serv.h
Serv_server.skeleton.cpp #簡單的server端代碼,可以修改,一般都參照它來寫serve程序
student_constants.cpp
student_constants.h
student_types.cpp
student_types.h
3.3 編寫客戶端client.cpp
#include "./gen-cpp/Serv.h"
#include </usr/local/include/thrift/transport/TSocket.h>
#include </usr/local/include/thrift/transport/TBufferTransports.h>
#include </usr/local/include/thrift/protocol/TBinaryProtocol.h>
#include <iostream>
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
//using boost::shared_ptr;
int main(int argc, char **argv) {
std::shared_ptr<TSocket> socket(new TSocket("127.0.0.1", 9090));
std::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
std::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
transport->open();
//*****************添加部分******************
Student s;
s.sno = 123;
s.sname = "xiaoshe";
s.ssex = 1;
s.sage = 30;
ServClient client(protocol);
std::cout<<"client send a data"<<std::endl;;
client.put(s);
//*****************添加部分******************
transport->close();
return 0;
}
編譯:g++ -g -o client -Ithrift client.cpp gen-cpp/Serv.cpp gen-cpp/student_types.cpp gen-cpp/student_constants.cpp -lthrift
3.4 服務端代碼
在Serv_server.skeleton.cpp中添加打印信息如下:
void put(const Student& s) {
// Your implementation goes here
printf("put\n");
printf("sno=%d sname=%s ssex=%d sage=%d/n", s.sno, s.sname.c_str(), s.ssex, s.sage); //********次行爲添加代碼********
}
編譯:g++ -g -o server -Ithrift Serv.cpp student_types.cpp student_constants.cpp Serv_server.skeleton.cpp -lthrift
3.5 編譯運行
(1)啓動服務端:./server
(2)啓動客戶端:./client
客戶端結果:
服務端結果:
注:更多測試用例可參照 thrift-0.13.0/test/ 目錄下的demo。
參考: