thrift之TTransport類體系原理及源碼詳細解析1-類結構和抽象基類
本章主要介紹Thrift的傳輸層功能的實現,傳輸的方式多種多樣,可以采用壓縮、分幀等,而這些功能的實現都是相互獨立,和上一章介紹的協議類實現方式比較雷同,還是先看看這部分的類關系圖,如下:
由上面的類關系圖可以看出,這部分的功能是相當的強大,所以類比較多且關系錯綜復雜。但是如果理解清楚了這些類直接的關系就很容易掌握這部分的實現技術和這部分實現的功能。我們把這個類關系圖分為三部分來看,第一部分看抽象基類TTransport類,它是所有傳輸類的基類,有很大一部分類直接從它繼承實現它提供或者說定義的接口函數(純虛函數),這些傳輸類功能比較單一實現也比較簡單;第二部分就是TTransport抽象類的默認實現和相應的子類以及加了一層虛擬傳輸類,這個傳輸虛擬類的類繼承框架個上一章的協議類虛擬繼承框架是相同的實現方案和技術,這樣實現可以避免采用虛擬繼承方式,因為虛擬繼承效率會比較低一些,虛擬繼承需要動態綁定技術(運行時去查找和指定具體的實現);第三部分就是各種傳輸類的對象生成工廠類,負責某一種具體傳輸類對象的生產。
第一節 抽象基類TTransport
本節介紹的是整個傳輸層實現的抽象概述,傳輸層實現的接口都在這個抽象基類中定義。下面看看傳輸層都實現了哪些接口?
1.輔助傳輸層的全局模板函數readAll
在開始分析傳輸層的接口以前先看一個輔助模板函數readAll,它的定義和實現如下:
template <class Transport_> uint32_t readAll(Transport_ &trans, uint8_t* buf, uint32_t len) { uint32_t have = 0; uint32_t get = 0; while (have < len) { get = trans.read(buf+have, len-have);//通過具體的傳輸類讀取剩余的需要讀取的數據 if (get <= 0) {//處理數據以讀完異常 throw TTransportException(TTransportException::END_OF_FILE, "No more data to read."); } have += get;//已經讀取的字節數 } return have;//返回讀到的字節數 }
這個函數現實比較簡單,就是通過一個while循環來保證需要讀取的字節數能夠讀完,如果字節數不夠就會拋出異常。
2.TTransport類的接口定義
下面用一個表格來分析TTransport抽象類定義的接口行為,如下:
|
函數名稱 |
函數參數描述 |
函數作用描述 |
|
isOpen |
無 |
傳輸層是否打開 |
|
peek |
無 |
測試是否有數據可讀或者遠程那邊是否任然打開。當傳輸是打開的默認為true,不過具體的實現邏輯需要根據可能的條件。 |
|
open |
無 |
為了通信打開傳輸層 |
|
close |
無 |
關閉傳輸層 |
|
read read_virt |
uint8_t* buf:讀入數據的本地緩存 uint32_t len:需要讀取數據的長度 |
嘗試讀取指定的字節數到字符串 |
|
readAll readAll_virt |
uint8_t* buf:讀入數據的本地緩存 uint32_t len:需要讀取數據的長度 |
無論如何都要讀取被給長度的數據 |
|
readEnd |
當讀取完成時調用 |
|
|
write write_virt |
uint8_t* buf:寫入數據的本地緩存 uint32_t len:需要寫入數據的長度 |
寫入字符串到緩存,必須調用flush函數后才真正的寫入,下次讀取的時候才是可利用的。 |
|
writeEnd |
無 |
寫入完成時調用 |
|
flush |
無 |
刷新任何被阻塞或緩存的數據真正被寫入 |
|
borrow borrow_virt |
uint8_t* buf:借入數據的緩存 uint32_t *len:需要借入數據的長度 |
嘗試返回一個指向len字節的字符串緩存并不是真正的讀取消耗它。這個函數主要用于可變長度編碼中,因為剛開始不知道具體長度。 |
|
consume consume_virt |
uint32_t len:消耗數據的長度 |
從傳輸層消耗len字節的數據,這個需要根據borrow函數具體使用的長度來決定。 |
通常一個傳輸層的對象要么作為輸出要么作為輸入,但是通常不能同時作為輸入和輸出。上面的表格中把所有支持的接口操作都簡單的介紹了,后面介紹的具體某一個傳輸層類的實現都會實現這些接口,只是根據各個子類不同的作用和實現方式有不同而已。特別需要注意的是最后兩組函數,這兩組函數主要是用于支持可變長度編碼的,所以如果傳輸層對象需要支持可變長度編碼必須實現這兩組函數。
浙公網安備 33010602011771號