前段時間用了一下Facebook的開源RPC框架Thrift,作PHP客戶端調用C++後端程序,真心以爲Thrift不錯!php
本文項目地址: https://github.com/zekunyan/ThriftDemo_PHP_CPPjava
先看看本文的例子示意圖:git
遠程過程調用(英語:Remote Procedure Call,縮寫爲 RPC)是一個計算機通訊協議。該協議容許運行於一臺計算機的程序調用另外一臺計算機的子程序,而程序員無需額外地爲這個交互做用編程。 — 維基百科 - 遠程過程調用程序員
通俗點講,就是跨計算機、跨網絡調用。github
Apache Thrift 是Facebook實現的一種高效的、支持多種編程語言的遠程服務調用(RPC)的框架。它採用接口描述語言定義並建立服務,支持可擴展的跨語言服務開 發,所包含的代碼生成引擎能夠在多種語言中,如 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk 等建立高效的、無縫的服務,其傳輸數據採用二進制格式,相對 XML 和 JSON 體積更小,對於高併發、大數據量和多語言的環境更有優點。 — Apache Thrift - 可伸縮的跨語言服務開發框架apache
在利用Thrift開發的過程當中,重點就是編寫接口定義文件。通常來講,接口定義文件決定了RPC過程當中的通訊數據結構、通訊接口定義等。編程
總的來講,thrift的接口定義語法相似於C語言,包含了struct、enum、map、list等基礎數據結構,同時支持大部分基本數據類型,如32位整型「i32」等。後端
詳細的接口定義請參考:瀏覽器
看看本例子中的定義文件「TTG.thrift」:網絡
namespace cpp TTG namespace php TTG enum ResponseState { StateOk = 0, StateError = 1, StateEmpty = 2 } struct Request { 1: i32 studentID = 0 } struct Response { 1: i32 studentID = 0, 2: string name, 3: list<string> infos, 4: ResponseState state } service TTGService { Response getStudentInfo(1: Request request); }
是的,生成代碼!這是我以爲Thrift框架最「神奇」的地方。咱們只須要執行幾條命令,就能夠根據接口定義文件「生成」對應語言的代碼。而後咱們只須要將對應的業務邏輯加入到生成的代碼中便可。
如生成CPP服務端的代碼:
thrift --gen cpp TTG.thrift
而後就會生成以下代碼。
TTGService.cpp TTGService.h TTGService_server.skeleton.cpp TTG_constants.cpp TTG_constants.h TTG_types.cpp TTG_types.h
生成CPP、PHP端的代碼之後,咱們就能夠根據須要修改、添加業務代碼。
在生成CPP的代碼時,會生成一個「TTGService_server.skeleton.cpp」文件,這個就是咱們的CPP服務端的代碼「架子」。其中重點以下:
//實現調用的接口 class TTGServiceHandler : virtual public TTGServiceIf { public: TTGServiceHandler() { // Your initialization goes here } //接口實現部分,實現getStudentInfo這個接口的具體細節,如根據request建立、返回對應的response void getStudentInfo(Response& _return, const Request& request) { // Your implementation goes here printf("getStudentInfo\n"); } }; //...
咱們將其改爲:
void getStudentInfo(Response &_return, const Request &request) { // 輸出請求參數 cout<<"Request: "<<request.studentID<<endl; // 建立返回數據 Response *response = new Response(); //填充數據 response->studentID = request.studentID; response->name = "tutuge"; response->infos.push_back("Info 1"); response->infos.push_back("Info 2"); response->state = ResponseState::StateOk; //返回 _return = *response; }
至此,CPP服務端的編寫就完成了,接下來咱們只須要編譯、連接,執行最終生成的可執行文件便可。
PHP客戶端的編寫比較簡單,直接參考代碼吧: https://github.com/zekunyan/ThriftDemo_PHP_CPP/blob/master/PHP/client.php
用CMake,或者直接編寫makefile都可,保證Thrift裝好就好了。
直接運行最後生成的可執行文件TTG.run便可。
從瀏覽器,或者直接運行client.php,便可看到以下輸出:
object(TTG\Response)[9] public 'studentID' => int 100 public 'name' => string 'tutuge' (length=6) public 'infos' => array (size=2) 0 => string 'Info 1' (length=6) 1 => string 'Info 2' (length=6) public 'state' => int 0
Thrift是個好東西!就是文檔好少=。=