RPC框架Thrift例子-PHP調用C++後端程序

前言

前段時間用了一下Facebook的開源RPC框架Thrift,作PHP客戶端調用C++後端程序,真心以爲Thrift不錯!php

本文項目地址: https://github.com/zekunyan/ThriftDemo_PHP_CPPjava

先看看本文的例子示意圖:git

流程

  1. PHP客戶端發起請求,請求參數是「Request」類型,裏面有studentID參數。
  2. CPP服務端收到請求返回數據,返回類型爲「Response」,裏面包含了student的信息,此處只是簡單的示例。

定義

什麼是RPC

遠程過程調用(英語:Remote Procedure Call,縮寫爲 RPC)是一個計算機通訊協議。該協議容許運行於一臺計算機的程序調用另外一臺計算機的子程序,而程序員無需額外地爲這個交互做用編程。 — 維基百科 - 遠程過程調用程序員

通俗點講,就是跨計算機、跨網絡調用。github

什麼是Thrift

Apache Thrift 是Facebook實現的一種高效的、支持多種編程語言的遠程服務調用(RPC)的框架。它採用接口描述語言定義並建立服務,支持可擴展的跨語言服務開 發,所包含的代碼生成引擎能夠在多種語言中,如 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk 等建立高效的、無縫的服務,其傳輸數據採用二進制格式,相對 XML 和 JSON 體積更小,對於高併發、大數據量和多語言的環境更有優點。 — Apache Thrift - 可伸縮的跨語言服務開發框架apache

開發流程

  1. 配置環境。C++的如CMake、make、g++;PHP的如php、php-fpm、Apache(Nginx)。
  2. 根據需求,編寫thrift接口定義文件(IDL定義文件)。
  3. 使用thrift程序,爲不一樣的語言生成代碼。
  4. 根據需求,修改生成的代碼(主要是Server端),編寫實際的業務邏輯。
  5. 編譯、部署。

Thrift的接口定義文件

在利用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);
}
  1. 先定義命名空間,儘可能減小命名衝突。
  2. Request類型:PHP客戶端請求的數據類型。
  3. Response類型:CPP服務端返回的數據類型。
  4. ResponseState枚舉:定義返回的狀態。
  5. TTGService:服務接口定義。

生成對應語言的代碼!

是的,生成代碼!這是我以爲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服務端

在生成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客戶端

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是個好東西!就是文檔好少=。=

相關文章
相關標籤/搜索