thrift簡介
thrift是一個用來進行可擴展且跨語言的服務的開發。它結合了功能強大的軟件堆棧和代碼生成引擎, 以構建在 C++, Java, Go,Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 這些編程語言間無縫結合的、高效的服務。
Thrift允許定義一個簡單的定義文件中的數據類型和服務接口,以作爲輸入文件,編譯器生成代碼用來方便地生成RPC客戶端和服務器通信的無縫跨編程語言。
—–百度百科
thrift代碼生成
在學習如何用thrift進行代碼生成時,可以先去看看thrift的官方文檔。
在這裏,可以看到thrift支持下面這些類型:
基本類型
- bool:一個bool值(true或false)
- byte:一個8位有符號整數
- i16:一個16位有符號整數
- i32:一個32位有符號整數
- i64:一個64位浮點數
- double:一個64位浮點數
- string:使用UTF-8編碼編碼的字符串
- 特殊類型
- binary:一個未編碼的字節隊列(這是上面string的一種特殊形式,爲了給java提供更好的互操作性而添加,目前計劃以後將這個類型提僧到基本類型。)
- 結構體
- struct :定義一個共同的對象,它本質上等同於OOP語言中的類,但是沒有繼承。結構體具有一組強類型字段,每個字段都有唯一的名稱標識符。字段可能有Thrift IDL中描述的各種註釋(數字字段ID,可選的默認值等)
- 容器
thrift的容器是強類型的容器,能夠映射到大多數編程語言中 常用的容器類型。
- list:元素的有序列表。相當於C#裏面的List< T>
- set:無序但唯一的一組元素。相當於C#裏面的THashSet< T>
- map:一個嚴格鍵唯一的鍵值對集合。相當於C#裏面的Dictionary< T1, T2>
- 異常
- exception:異常在功能上等同於結構,除了它們在每種目標編程語言中適當地繼承本機異常基類以便與任何給定語言中的本地異常處理無縫集成。
- 服務
- service:服務的定義在語義上等同於在面向對象編程中定義接口(或純虛擬抽象類)。Thrift編譯器生成實現該接口的功能齊全的客戶端和服務器存根。
一個服務由一組命名函數組成,每個函數都有一個參數列表和一個返回類型。
請注意,除了所有其他定義的Thrift類型之外,void是函數返回的有效類型。此外,使用oneway修飾的void返回值函數將生成不等待響應的代碼。請注意,被void修飾的函數將返回一個響應到客戶端,保證在服務器端的操作已經完成。使用oneway方法調用服務將只能保證請求在傳輸層成功。同一客戶端的oneway方法調用可以由服務器並行/不按順序執行。
- service:服務的定義在語義上等同於在面向對象編程中定義接口(或純虛擬抽象類)。Thrift編譯器生成實現該接口的功能齊全的客戶端和服務器存根。
下面列舉一個簡單的thrift文件實例:
namespace csharp DemoService.Interface
struct Demo
{
1:i32 Id,
2:map<string,string> parm1,
3:set<string> parm2,
}
service DemoService
{
bool AddDemo(1:Demo demo)//增加
bool DeleteDemo(1:list<i32> id)//刪除
bool UpdateDemo(1:Demo demo)//修改
Demo GetDemoById(1:i32 id)//根據Id查詢
list<Demo> GetAllDemo()//查詢所有
}
打開cmd窗口,將路徑切換到thrift.exe的路徑下,並將上面的文件保存到一個新建的txt文檔中,修改後綴名爲.thrift。官網下載路徑爲:thrift官網下載
運行下面命令:
thrift.exe -gen csharp demo.thrift(自己保存的文件名)
就會在該目錄下生成一個gen-csharp的文件夾,裏面會有一個DemoService的文件夾,裏面會有一個Inteface文件夾(這2個文件夾根據namespace後面的名稱生成)。裏面會有2個文件:Demo.cs、DemoService.cs。
裏面分別對應了struct和service之後的內容。
Demo.cs簡要內容:
DemoService.cs簡要內容:
通過上面的內容,可以看到map< string,string>將會轉換成Dictionary< string, string>,set< string>將轉換成THashSet< string>,在DemoService中,將生成一個包含了thrift文件標識的函數接口。這2個文件將服務端和客戶端通信的關鍵。在服務端,需要繼承這個接口,並實現接口中的函數。在客戶端實例化DemoService中的Client,在Client類中也會有接口中方法的實現(就不具體展開了,有興趣的可以自行查看DemoService的具體內容,還有很多遠程調用的協議之類的說明。),然後調用client裏面的方法,就可以調用到服務端的方法了。
thrift客戶端與服務端創建(C#)
服務端
服務端服務啓動代碼:
static void StartService()
{
try
{
//設置服務端口爲8080
TServerSocket serverTransport = new TServerSocket(8080);
//設置傳輸協議工廠
TBinaryProtocol.Factory factory = new TBinaryProtocol.Factory();
//關聯處理器與服務的實現
TProcessor processor = new DemoService.Processor(new DemoAchieveService());
//創建服務端對象
TServer server = new TThreadPoolServer(processor, serverTransport, new TTransportFactory(), factory);
Console.WriteLine("服務端正在監聽8080端口");
server.Serve();
}
catch (TTransportException ex)
{
Console.WriteLine(ex.Message);
}
}
服務端還需要實現一個具體的類,上面代碼中的DemoAchieveService類,這個類需要繼承自DemoService.Iface,並且實現接口裏面的方法,具體內容就展示了。
客戶端
客戶端創建Client代碼:
/// <summary>
/// 創建客戶端
/// </summary>
/// <returns></returns>
public DemoService.Client CreateClient()
{
try
{
//設置服務端端口號和地址
TTransport transport = new TSocket("127.0.0.1", 8080);
transport.Open();
//設置傳輸協議爲二進制傳輸協議
TProtocol protocol = new TBinaryProtocol(transport);
//創建客戶端對象
DemoService.Client client = new DemoService.Client(protocol);
return client;
}
catch (Exception ex)
{
throw;
}
}
創建好Client後,通過client調用方法就可以了。