這一部分主要實現了底層IO通信,還涉及到通信服務器的堵塞、非堵塞、單線程、多線程等運行模式,所以實現比較複雜。這一部分涉及到的類的關係圖如下:
由上面的類關係圖可以看出,這一部分的類關係比較複雜,複雜的不是繼承關係,而是相互之間的依賴關係。因爲服務器需要處理很多的任務,也需要處理多個客戶端的連接,這就涉及到多線程編程以及多線程之間通信及併發的情況。這一部分涉及到的併發編程的類容將在後面章節單獨分析,本章主要介紹服務器模型和IO通信的具體細節。
第一節 服務器基類TServer
所有具體的服務器模型實現類都從一個共同的基類繼承,這個基類就是本節介紹的TServer類,這個類又從Runnable繼承,Runnable類是一個實現多線程的抽象類,類似java裏面的。下面分別從成員變量的定義、構造函數和其他相關函數介紹TServer定義的功能。
1.成員變量定義
一個類的成員變量定義基本上能夠體現出類的屬性,首先看看主要成員變量的定義及其作用:
boost::shared_ptr<TProcessorFactory> processorFactory_;//處理層的對象生成工廠對象
boost::shared_ptr<TServerTransport> serverTransport_;//服務器傳輸對象
boost::shared_ptr<TTransportFactory> inputTransportFactory_;//輸入傳輸層工廠對象
boost::shared_ptr<TTransportFactory> outputTransportFactory_;//輸出傳輸層工廠對象
boost::shared_ptr<TProtocolFactory> inputProtocolFactory_;//輸入協議層工廠對象
boost::shared_ptr<TProtocolFactory> outputProtocolFactory_;//輸出協議層工廠對象
boost::shared_ptr<TServerEventHandler> eventHandler_;//服務器事件處理對象類
Thrift的服務器類基本上把其他所有層的功能綜合起來了,這樣每一個不同的服務器模型實現都可以組裝不同的處理層邏輯(主要根據用戶定義的邏輯接口定義語言代碼字段生成的一層)、協議層和傳輸層,在加上一個單獨處理事件的類,整個服務器就相當的強大而且靈活。這些對象都是抽象基類的對象,需要在實例化的時候依賴具體的子類實現。
2.構造函數
構造函數的主要作用就是初始化上一節定義的成員變量,提供了多個版本的構造函數,根據需要具體初始的成員變量定義,例如如果需要指定一個具體的處理層的工廠對象以便生成對應需要的處理層類對象構造函數定義如下:
template<typename ProcessorFactory>
TServer(const boost::shared_ptr<ProcessorFactory>& processorFactory,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& transportFactory,
const boost::shared_ptr<TProtocolFactory>& protocolFactory,
THRIFT_OVERLOAD_IF(ProcessorFactory, TProcessorFactory)):
processorFactory_(processorFactory),
serverTransport_(serverTransport),
inputTransportFactory_(transportFactory),
outputTransportFactory_(transportFactory),
inputProtocolFactory_(protocolFactory),
outputProtocolFactory_(protocolFactory) {}
構造函數都是模板函數,但是隻會針對具體類的對象特化,例如上面代碼就只會針對模板參數是TProcessorFactory類進行特化,做到這一點的是宏定義:
THRIFT_OVERLOAD_IF(ProcessorFactory, TProcessorFactory)//如果模板參數ProcessorFactory能夠轉換爲TProcessorFactory那麼就特化這個版本函數
------>#define THRIFT_OVERLOAD_IF(T, Y) \
THRIFT_OVERLOAD_IF_DEFN(T, Y) = NULL
------>#define THRIFT_OVERLOAD_IF_DEFN(T, Y) \
typename ::boost::enable_if<typename ::boost::is_convertible<T*, Y*>::type, \
void*>::type
這個是利用了boost庫的功能,具體參考boost庫幫助文檔。還有好幾個這樣的構造函數,只是參數不同而已,沒有傳遞的參數就new一個默認的對象來初始化,以後調用函數來設置就可以了,下面就介紹這些函數。
3.Get和Set函數
Get和Set函數主要針對一些成員變量進行賦值和取值,例如針對輸入協議類對象的設置和獲取函數如下定義和實現:
void setInputProtocolFactory(boost::shared_ptr<TProtocolFactory> inputProtocolFactory) {
inputProtocolFactory_ = inputProtocolFactory;
}
boost::shared_ptr<TProtocolFactory> getInputProtocolFactory() {
return inputProtocolFactory_;
}
其他成員變量也都有類似的函數對。
4.其他函數
這些函數主要是實現具體服務器功能的函數了,每一個具體的服務器模型類都需要實現以滿足一個服務器的基本需求,當然實現不同功能差別也很大,例如執行異步多線程、連接池、線程池等。
先重點介紹一個獲取處理邏輯類對象的函數,定義如下:
boost::shared_ptr<TProcessor> getProcessor(
boost::shared_ptr<TProtocol> inputProtocol,
boost::shared_ptr<TProtocol> outputProtocol,
boost::shared_ptr<TTransport> transport) {
TConnectionInfo connInfo;
connInfo.input = inputProtocol;
connInfo.output = outputProtocol;
connInfo.transport = transport;
return processorFactory_->getProcessor(connInfo);//調用具體處理層工廠類的相應函數獲取
}
這裏又出現一個新的結構體連接信息對象TConnectionInfo ,主要作用就是記錄輸入輸出協議類和服務器傳輸對象。這個函數根據輸入輸出協議類和傳輸層對象構造一個具體的處理類對象(在前已經具體介紹過實現和功能了)。其他重要函數定義如下:
virtual ~TServer() {}
virtual void serve() = 0;
virtual void stop() {}
// Allows running the server as a Runnable thread
virtual void run() {
serve();
}
每一個具體服務器模型子類都會重點實現這些函數,特別是serve函數。Run函數就是線程運行時執行的這個函數開始提供服務了。