前言
本文將介紹由 Facebook 開發的遠程服務調用框架 Apache Thrift,它采用接口描述語言定義並創建服務,支持可擴展的跨語言服務開發,所包含的代碼生成引擎可以在多種語言中,如 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk 等創建高效的、無縫的服務,其傳輸數據采用二進制格式,相對 XML 和 JSON 體積更小,對於高並發、大數據量和多語言的環境更有優勢。本文將詳細介紹 Thrift 在C#語言下的使用方式,並且提供豐富的實例代碼加以解釋說明,幫助使用者快速構建服務。
完善開發工具
通過nuget在vs2019中安裝thrift
在項目中引用右鍵點擊管理Nuget程序包,在打開的界面輸入thrift,如下圖:
我們選擇ApacheThrift這一項進行安裝,安裝后,在我們項目里有Thrift45.dll的引用,如下圖:
下載thrift代碼生成工具
thrift是支持異構語言、異構平台的通信開發RPC框架,它通過中間語言IDL進行描述你要定義的結構、類、服務等,並通過代碼生成工具生成各個語言上對應的代碼。
接下來,我們進入Apache網站Thrift項目下載Thrift代碼生成工具,如下圖:
我們把下載的這個exe文件放到我們項目的根目錄下,以備后用,如下圖:
至此,關於thrift的開發工具,我們已經准備完畢,接下來來編寫thrift接口描述文件
thrift描述文件
thrift提供的接口描述文件是以thrift結尾的格式文件,我們來解釋一下這種IDL的語法,
- 它提供了基礎類型的定義,包括bool、i16、i32、i64、double、string
- enum
- Struct 對一些基礎類型的封裝,對應C#中Class字段
- 還有一些集合的定義,包含 set<> 對應C#中的HashSet,是一種唯一元素的集合(Thrift框架自己定義了THashSet類型與之相對應);list<>對應C#中的List<>;map<K,V>對應C#的Dictionary<K,V>
- service 這個是thrift的重點,它是一些方法集合,thrift會根據這個定義生成客戶端代碼和服務端代碼
- exception 對應C#中的Exception類型
thrift關於類型的定義以及示例代碼請打開這個網址:IDL描述
在IDL描述文件中,Thrift除了對類型的定義外,我們還需要記住一下知識點:
- namespace 在描述文件的頭部定義。 以當前文件為根目錄,生成多級目錄;在生成的代碼上添加namespace命名空間。代碼如下:
namespace csharp WpfApp1.ceshi
- include 在描述文件的頭部定義。 用該命令包含其他thrift描述文件,當編譯生成代碼時也會編譯include指定的thrift文件。代碼如下:
include "pe1.thrift"
使用方法,pe1.thrift文件定義如下:
struct pe1
{
1: i32 id;
}
在其他文件中,引入上述文件,定義如下:
include "pe1.thrift"
service GuidGenService
{
string getGuid(1:pe1.pe1 pe1);
}
- typedef 類型定義命令,將thrift支持的類型定義一個別名。代碼如下:
typedef i32 int
struct People
{
1: int ID;
2: string Name;
3: i16 Age;
4: list<i32> onelist;
5: set<string> oneSet;
6: map<i32,string> oneset;
}
當定義完描述文件后,我們通過如下cmd命令生成代碼文件:
thrift-0.12.0.exe -r -gen csharp People.thrift
我們先要通過cd 將當前路徑跳轉到thrift-0.12.0.exe所在的路徑
示例
我定義了了一個描述文件,如下:
namespace csharp WpfApp1.ceshi
include "pe1.thrift"
typedef i32 int
struct People
{
1: int ID;
2: string Name;
3: i16 Age;
4: list<i32> onelist;
5: set<string> oneSet;
6: map<i32,string> oneset;
}
service HelloService
{
void SetPeople(1: People people1);
}
service GuidGenService
{
string getGuid(1:pe1.pe1 pe1);
}
我們通過上述命令執行后,生成的代碼結構如下圖:
我們打開people.cs可以看到struct people生成了如下代碼:
namespace WpfApp1.ceshi
{
#if !SILVERLIGHT
[Serializable]
#endif
public partial class People : TBase
{
private int _ID;
private string _Name;
private short _Age;
private List<int> _onelist;
private THashSet<string> _oneSet;
private Dictionary<int, string> _oneset;
.....
這里需要注意一下people類的命名空間,這和我們上文講的時一致的。
我們定義的service GuidGenService生成了如下代碼:
該類是我們使用該框架的重點,它給我們生成了客戶端和服務器端代碼,從圖中我們可以看該文件下生成了兩個接口ISync和Iface,前者是同步方法,后者生成的是異步調用方法,接下來是一個供我們客戶端調用的類,它繼承了iface接口,而iface又繼承了ISync接口;再往下看是一個Processor,是服務端使用的類。
結尾
這篇文件我們講了從0到1使用thrift框架的方法,也講了一些該框架的基本知識,接下來的文件,我們將通過一個示例具體講解一下service指令代碼生成的代碼的具體含義和使用方法