通過向導創建一個uniGUI應用服務器,工程中有三個文件:
TUniServerModule = class(TUniGUIServerModule) TUniMainModule = class(TUniGUIMainModule) TMainForm = class(TUniForm)
(1)采用了單例模式,所有客戶端共用一個TUniServerModule實例對象,從下面代碼可以看出:
function UniServerModule: TUniServerModule; implementation {$R *.dfm} uses UniGUIVars; function UniServerModule: TUniServerModule; begin Result:=TUniServerModule(UniGUIServerInstance); end; initialization RegisterServerModuleClass(TUniServerModule);
用全局變量UniGUIServerInstance實現了唯一化的TUniServerModule實例對象,可以視同為全局控制對象,將一些需要唯一化的對象構建在TUniGUIServerModule類中,比如可以考慮構建數據庫連接池,如果有必要也可以構建對象池。
(2)每個客戶端連接后,系統創建了一個TUniMainModule對象,用於支撐和管理每個客戶端連接,實現機理由於沒有源碼還暫時看不出,其實例的獲取代碼如下:
function UniMainModule: TUniMainModule; implementation {$R *.dfm} uses UniGUIVars, ServerModule, uniGUIApplication; function UniMainModule: TUniMainModule; begin Result := TUniMainModule(UniApplication.UniMainModule) end;
通過全局變量UniApplication的屬性UniMainModule實現對TUniMainModule實例對象的調用,如何區分不同客戶端連接的還不清楚。類的注冊代碼如下:
initialization RegisterMainModuleClass(TUniMainModule);
TUniGUIMainModule實例視同每個連接的控制對象,可以將數據庫連接和數據集放在該類中,如果數據集非常多,也可以考慮動態創建多個TDataModule,並由TUniGUIMainModule實例進行管理和維護。如果是三層結構,則TSQLConnection也應放在這個Module中。
(3)主窗體是一個TUniForm類,且是一個Application構建的窗體,通過注冊實現,如下:
function MainForm: TMainForm; implementation {$R *.dfm} uses uniGUIVars, MainModule, uniGUIApplication; function MainForm: TMainForm; begin Result := TMainForm(UniMainModule.GetFormInstance(TMainForm)); end;
通過以下代碼進行注冊
initialization RegisterAppFormClass(TMainForm);
所有Application構建窗體都是通過上述方式實現,由Application控制其生命周期。也可以自定義Free窗體,自己控制窗體的創建和釋放。
總之,可以將TUniServerModule實例對象視作全局控制對象,TUniMainModule對象視作每個連接控制對象,第一個注冊的TUniForm類Application窗體為主窗體。
(4)對每個連接線程的訪問可以通過UniServerModule.SessionManager.Sessions獲取並作進一步處理,如下:
procedure TUniMainModule.UniGUIMainModuleCreate(Sender: TObject); var I : Integer; ASessionList: TList; ASession : TUniGUISession; begin { 鎖定列表 } ASessionList := UniServerModule.SessionManager.Sessions.SessionList.LockList; try { 訪問每個線程 } for I := 0 to ASessionList.Count-1 do begin ASession := TUniGUISession(ASessionList[I]); if not ASession.IsTerminated then { 進行處理,如客戶端地址 ASession.UniApplication.RemoteAddress } end; finally { 釋放列表 } UniServerModule.SessionManager.Sessions.SessionList.UnlockList; end; end;
也可以在TUniMainModule實例或TUniForm實例中直接訪問當前線程對象,如:
procedure TUniMainModule.UniGUIMainModuleDestroy(Sender: TObject); var strClientIP : String; begin strClientIP := UniSession.UniApplication.RemoteAddress; { 進一步處理 } end;