thrift安裝及示例

1. 簡介

  Apache Thrift軟件框架(用於可擴展的跨語言服務開發)將軟件堆棧與代碼生成引擎結合在一起,它有自己的跨機器的通信框架,並提供一套庫。它是一個代碼生成器,按照它的規則,可以生成多種編程語言(C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell,C#, Cocoa,JavaScript,Node.js,Smalltalk,OCaml和Delphi等語言)的通訊過程代碼。
  簡單說就是支持跨語言跨平臺通信。比如服務器和客戶端通信,但是兩端用的平臺和編程語言都不一樣,就可以用thrift輕鬆解決。
  那它是怎麼解決跨語言通信的呢?至於技術本身原理這裏不深挖了,只寫用戶需要做什麼。對於用戶而言,只需寫一個*.thrift文件,定義通信數據(如結構體)和函數。舉個簡單例子,在服務器上我們實現了一個計算器的功能,在客戶端需要給出計算的數字和符號。那麼計算器函數接口和參數都需要在 *.thrift文件中定義,然後在服務器和客戶端分別用thrift的命令行生成對應語言的函數。具體的見後文。
  下面我們開始安裝並使用吧~

2. 開始

2.1 下載

Thrift下載地址
在這裏插入圖片描述
Ubuntu下載後進入下載目錄,利用tar -zxvf命令解壓

tar -zxvf thrift-0.13.0.tar.gz

(注:我沒有使用鏡像資源,而是git clone了源碼,因爲鏡像編譯不過去,但是git下來的就不會報一堆奇奇怪怪的錯誤)

git clone https://github.com/apache/thrift.git
cd thrift

Windows需要下載.exe文件,可以不用下源碼。exe本身就是編譯好給windows用戶使用的。

2.2 編譯並安裝Apache Thrift編譯器

2.2.1 安裝依賴環境(C++)

sudo apt-get install automake bison flex g++ git libboost-all-dev libevent-dev libssl-dev libtool make pkg-config

如果用其他語言,安裝相關庫(這裏只列常用,其他參考官網

  • Java
    packages: gradle
    JDK v1.8或以上版本.
apt-get install default-jdk
  • Python
    python-all
    python-all-dev
    python-all-dbg
  • Php, install
    php5-dev
    php5-cli
    phpunit

2.2.2 編譯

第一次從源碼編譯,需要生成配置腳本

./bootstrap.sh

配置thrift

./configure

其他配置選項可以使用help查看

./configure --help

make :這個過程可能會有點長,可以通過-j*參數加快速度,具體j後面數字是多少,看你自己電腦核數。

make -j16

測試

make check
sh test/test.sh

2.2.3 編譯報錯情況

  • “compiler/cpp/thriftl.cc:2190: undefined reference to `yywrap’”

 安裝 Flex library,然後重新配置

  • mv: cannot stat “’.deps/TBinaryProtocol.Tpo’: No such file or directory” while building the Thrift Runtime Library

 重新配置

./configure --enable-libtool-lock

 或者

make -j 1

2.2.4 安裝

sudo make install

最好make和make install都在sudo下執行,否則會報權限不足錯誤。

2.3 編寫.thrift文件

  下面可以開始使用thrift了。一切都要從編寫thrift文件開始。該文件是定義thrift類型(參數)和服務(函數)的接口。其中服務是指在服務端實現,被客戶端調用的函數。thrift編譯器用於將thrift文件生成不同語言的源碼。
  使用thrift編譯器生成源碼的命令格式:

thrift --gen <language> <Thrift filename>

  關於thrift更多內容可以參考文章Thrift: Scalable Cross-Language Services Implementatio
在這裏插入圖片描述

3. 例子

3.1 目標

  實現加法計算。

3.2 calculator.thrift

service CalculatorService {
	i32 add(1:i32 num1, 2:i32 num2),
}

然後命令行進入.thrift目錄下,執行

thrift -r --gen cpp calculator.thrift

命令執行完會生成gen-cpp文件夾,裏面包含7個文件
在這裏插入圖片描述
其中skeleton是一個服務端框架,需要自己實現;
我們用到的大部分內容都在Service裏。

3.3 服務端-Calculator-server.cpp

將CalculatorService_server.skeleton.cpp拷貝出來,更改名稱爲calculator-server.cpp,並修改add函數

int32_t add(const int32_t num1, const int32_t num2) {
    // Your implementation goes here
    return num1+num2;
    printf("add\n");
  }

並修改包含目錄

#include "./gen-cpp/CalculatorService.h"

3.4 客戶端-Calculator-client.cpp

將Calculator-server.cpp拷貝修改文件名爲Calculator-client.cpp,並修改code如下:

// This autogenerated skeleton file illustrates how to build a server.
// You should copy it to another filename to avoid overwriting it.

#include "./gen-cpp/CalculatorService.h"
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportUtils.h>
#include <iostream>

using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;

using namespace std;

int main(int argc, char **argv) {
    std::shared_ptr<TTransport> socket(new TSocket("localhost", 9090));
    std::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
    std::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
    CalculatorServiceClient client(protocol);

    try
    {
        transport->open();

        int result, addarg1, addarg2;
	while(1)
	{
	    cout << "please input arg1:";
	    cin >> addarg1;
	    cout << "please input arg2:";
	    cin >> addarg2;
        result = client.add(addarg1, addarg2);
        cout << "result is :" << result << endl;
	    transport->close();
	}
        // transport->close();
    }
    catch (TException &tx)
    {
        cout << "ERROR: " << tx.what() << endl;
    }
}

3.5 CMakeLists.txt

可以通過vscode創建cmakelists。通過Ctrl + Shift + P 來打開命令行,輸入cmake然後選擇CMake:Quick Start

cmake_minimum_required(VERSION 3.0.0)

# 尋找Boost庫
# find_package(Boost REQUIRED)
# include_directories(SYSTEM "${Boost_INCLUDE_DIRS}")
set(Thrift_DIR /home/dreamdeck/Downloads/thrift/build/cmake) 
set(CMAKE_MODULE_PATH ${Thrift_DIR})
include(BoostMacros)
REQUIRE_BOOST_HEADERS()

# 尋找thrift
include(ThriftMacros)

#Make sure gen-cpp files can be included
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
include_directories("${CMAKE_CURRENT_BINARY_DIR}/gen-cpp")
include_directories("${PROJECT_SOURCE_DIR}/lib/cpp/src")

# include(ThriftMacros)

# 源碼集合
set(calculatorgencpp_SOURCES
    gen-cpp/CalculatorService.cpp
    gen-cpp/calculator_constants.cpp
    gen-cpp/calculator_types.cpp
)
# 生成靜態庫目標
add_library(calculatorgencpp STATIC ${calculatorgencpp_SOURCES})
LINK_AGAINST_THRIFT_LIBRARY(calculatorgencpp thrift)

# 生成calculator_server可執行程序,要求連接test靜態庫,thrift庫
add_executable(calculator_server Calculator_server.cpp)
target_link_libraries(calculator_server ${OpenCV_LIBS})
target_link_libraries(calculator_server calculatorgencpp)
LINK_AGAINST_THRIFT_LIBRARY(calculator_server thrift)
if (ZLIB_FOUND)
  target_link_libraries(calculator_server ${ZLIB_LIBRARIES})
endif ()

# 生成calculator_client可執行程序,要求連接test靜態庫,thrift庫
add_executable(calculator_client Calculator_client.cpp)
target_link_libraries(calculator_client ${OpenCV_LIBS})
target_link_libraries(calculator_client calculatorgencpp)
LINK_AGAINST_THRIFT_LIBRARY(calculator_client thrift)
if (ZLIB_FOUND)
  target_link_libraries(calculator_client ${ZLIB_LIBRARIES})
endif ()

3.6 Makefile

  • 如果寫了CMakeLists.txt,則進入build文件夾(沒有的話就新建一個)執行:(其中…表示上一級目錄)
cmake ..

cmake成功後如下
在這裏插入圖片描述

  • 或者在vscode裏通過Ctrl + Shift + P 來打開命令行,輸入cmake然後選擇CMake:Configure

  • 如果沒寫cmakelists,也可以自己編寫Makefile

APP:= calculator-app

TARGET_DEVICE = $(shell g++ -dumpmachine | cut -f1 -d -)
ifeq ($(TARGET_DEVICE),aarch64)
  CFLAGS:= -DPLATFORM_TEGRA
endif

SRCS:= $(wildcard ./thrift/gen-cpp/*.cpp)
OBJS+= $(SRCS:.cpp=.o)

CFLAGS+= -I/usr/local/include/thrift -I./thrift/gen-cpp
LIBS+= -L/usr/local/lib/ -lthrift 

CFLAGS+= `pkg-config --cflags $(PKGS)`
LIBS+= `pkg-config --libs $(PKGS)`

all: $(APP)

%.o: %.c $(INCS) Makefile
	$(CXX) -c -o $@ $(CFLAGS) -g $<

$(APP): $(OBJS) Makefile
	$(CXX) -o $(APP) $(OBJS)  $(LIBS) 

clean:
	rm -rf $(OBJS) $(APP)

3.7 make並run

執行make,然後

make

結果如下
在這裏插入圖片描述
然後打開兩個terminal分別執行

./calculator_server 
./calculator_client

結果如下:
在這裏插入圖片描述
其他語言的client類似。只需重新用thrift編譯成對應語言源碼,再寫client。

(完結)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章