在Equalizer中,server作為一個獨立啟動並執行進程,負責整個並行繪製系統的管理與調度,其主要任務包括載入配置指令碼,監聽並與各節點建立串連,響應來自其它節點的訊息等。由於eq::Server是eq::Node的子類,因此在很多方面與後者比較相似。
1.載入配置指令碼 在eq::Server的初始化階段,eq::Server::Loader及其多個重載函數可以從命令列中的字串或指令檔(*.cfg)中載入關於應用的配置,並據此建立eq::Server以及eq::Config對象。無論是採用那種配置方式,都以字串形式載入並由server/parser.cpp中的函數實現解析,該過程是採用Bison-Flex自動產生的。事實上,這裡的eq::Config就是要在收到其它應用節點的串連請求後,需要向其發送的配置參數。
2.網路通訊 eq::Server繼承自eq::net::Node,初始化過程直接採用父類的操作,其中的關鍵在於啟動監聽功能。預設的監聽採用TCP/IP協議對指定連接埠進行監聽,也可以在命令列參數中輸入由“--eq-listener”參數指定的網路通訊協定與監聽連接埠,可用的協議包括TCP/IP、SDP和PIPE三種。 eq::net::Node的初始化時,可以在命令列參數中輸入“--eq-client”,並在其後的參數中標明要啟動並執行用戶端指令,從而建立作為用戶端的節點對象,也就是所謂的“alone”運行模式。
eq::net::Node中的資料發送、接收,都是由其中的成員對象_connect完成。該對象為eq::net::Connection的對象指標,在win32下執行個體化為socketConnectionWin32對象,它採用WinSock的overlapped模型進行資料的發送接收。其實質是以多線程形式的阻塞模式,實現資料的非同步傳輸。同時,Connection類也提供了直接面對資料緩衝與Packet結構體的傳輸介面,從而簡化了其在eq::net::Node中的應用。
在eq::net::Connection中,send/recv是進階介面,由應用對象,如eq::net::Node調用,而read/write是底層介面,用於直接處理資料轉送的socket操作。高層介面內部通過底層介面執行網路操作,其介面與底層操作無關,因此由eq::net::Connection類直接實現。而底層的read/write所使用的介面與啟動並執行平台相關,例如在windows中使用WinSock,在有的環境下會採取共用快取方式,所以由不同的子類實現,如。
3.訊息響應
eq::net::Node在初始化監聽後會啟動兩個線程,分別用於接收監聽到的資料以及處理資料中的指令,所有的資料都以訊息的形式進程處理。其中_receiverThread用於將接收到的訊息放入node的訊息佇列,而_commandThread則從訊息佇列中依次擷取訊息並根據訊息執行操作。eq::Server在完成初始化後,會進入訊息處理迴圈,不斷從訊息佇列中獲得新的訊息並進行處理。
eq::net::Node中利用eq::net::ConnectionSet實現非同步網路通訊,並根據所接收到的訊息進行簡單響應。需要注意的是,這裡通過非同步接收到的訊息並不是有效應用訊息。除了必要的異常訊息外,Event_Data是其中最主要的訊息,該訊息中還包括收到該訊息的connector,以及相應的資料大小。在_receiveThread線程中就是首先查詢eq::net::ConnectionSet,當出現Event_Data訊息後,即根據該訊息的參數進行同步的資料接收真正有效訊息資料。(這種方式下,首先通過簡單的非同步訊息避免了接收線程中不斷的主動查詢連接埠,然後只有在明確有有效資料到達時才讀取連接埠,效率相對較高)