unit uROOlympiaSessionManager; {----------------------------------------------------------------------------} { RemObjects SDK Library - Core Library } { } { compiler: Delphi 5 and up, Kylix 2 and up } { platform: Win32, Linux } { } { (c)opyright RemObjects Software. all rights reserved. } { } { Using this code requires a valid license of the RemObjects SDK } { which can be obtained at http://www.remobjects.com. } {----------------------------------------------------------------------------} {$I RemObjects.inc} interface uses Classes, uROClient, uROSessions, uROBinMessage, uROTypes, ROOlympia_Intf,uROEventRepository; type { TROOlympiaSessionManager } TROOlympiaSessionManager = class(TROCustomSessionManager,IOlympiaSessionManagerEvents) private fBINMessage : TROBinMessage; // fChannel: TROTransportChannel; // fSessionManager : IOlympiaSessionManager; fApplicationID : TGUID; fApplicationID_Ansi: AnsiString; FActive: Boolean; fStreamedActive: Boolean; FEventReceiver: TROEventReceiver; procedure SetChannel(const Value: TROTransportChannel); function GetSessionManager: IOlympiaSessionManager; procedure SetApplicationID(const Value: TGUID); procedure SetActive(const Value: Boolean); function GetChannel: TROTransportChannel; protected procedure Notification(AComponent: TComponent; Operation: TOperation); override; procedure Loaded; override; { Overrides } function DoFindSession(const aSessionID : TGUID; aUpdateTime: Boolean) : TROSession; override; procedure DoDeleteSession(const aSessionID : TGUID; IsExpired : boolean); override; procedure DoClearSessions(OnlyExpired : boolean); override; function DoGetSessionCount : integer; override; procedure DoReleaseSession(aSession : TROSession; NewSession : boolean); override; procedure DoGetAllSessions(Dest: TStringList); override; function DoCheckSessionIsExpired(aSession : TROSession) : boolean; override; property SessionManager : IOlympiaSessionManager read GetSessionManager; property OnSessionDeleted; property EventReceiver: TROEventReceiver read FEventReceiver; procedure SessionsExpired(const aExpiredSessionIDs: GuidArray); public constructor Create(aOwner : TComponent); override; destructor Destroy; override; procedure CheckProperties; override; {$IFDEF FPC} property ApplicationID: TGUID read FApplicationID write SetApplicationID; {$ENDIF} property Active: Boolean read FActive write SetActive; procedure Assign(Source: TPersistent); override; published property Channel : TROTransportChannel read GetChannel write SetChannel; {$IFNDEF FPC} property ApplicationID: TGUID read FApplicationID write SetApplicationID; {$ENDIF} end; implementation uses SysUtils, uROClientIntf, uROClasses, uRORes {$IFDEF MSWINDOWS},Windows{$ENDIF}; { TROOlympiaSessionManager } procedure TROOlympiaSessionManager.Assign(Source: TPersistent); var lSource: TROOlympiaSessionManager; begin inherited; if Source is TROOlympiaSessionManager then begin lSource := TROOlympiaSessionManager(Source); ApplicationID := lSource.ApplicationID; Channel := lSource.Channel; end; end; procedure TROOlympiaSessionManager.CheckProperties; begin Check(Channel = nil, Name + '.Channel must be assigned.'); Channel.CheckProperties; end; constructor TROOlympiaSessionManager.Create(aOwner: TComponent); begin inherited; fBINMessage := TROBinMessage.Create(Self); FEventReceiver := TROEventReceiver.Create(self); ApplicationID := NewGuid; // in order to kill checktimer set interval to 0 Self.SessionCheckInterval := 0; end; destructor TROOlympiaSessionManager.Destroy; begin if FActive then Active :=False; FEventReceiver.Deactivate; Channel := nil; inherited; end; function TROOlympiaSessionManager.DoCheckSessionIsExpired( aSession: TROSession): boolean; begin Result := not SessionManager.CheckSession(GUIDToAnsiString(aSession.SessionID)); end; procedure TROOlympiaSessionManager.DoClearSessions( OnlyExpired: boolean); begin SessionManager.ClearSessions(fApplicationID_Ansi); end; procedure TROOlympiaSessionManager.DoDeleteSession( const aSessionID: TGUID; IsExpired: boolean); begin SessionManager.DeleteSession(GUIDToAnsiString(aSessionID)); end; function TROOlympiaSessionManager.DoFindSession( const aSessionID: TGUID; aUpdateTime: Boolean): TROSession; var usersession : OlympiaUserSession; {$IFDEF MSWINDOWS}lZI: TIME_ZONE_INFORMATION;{$ENDIF} begin result := NIL; usersession := SessionManager.ReadSession(GUIDToAnsiString(aSessionID)); if (usersession<>NIL) then try result := DoCreateSession(aSessionID); result.Created := usersession.Created; {$IFDEF MSWINDOWS} GetTimeZoneInformation(lZI); result.LastAccessed := usersession.LastAccessed - (lZI.Bias + lZI.StandardBias + lZI.DaylightBias)/1440.0; {$ELSE} result.LastAccessed := usersession.LastAccessed; {$ENDIF} result.LoadFromStream(usersession.Data, TRUE); finally usersession.Free; end; end; procedure TROOlympiaSessionManager.DoGetAllSessions(Dest: TStringList); var lArray: GuidArray; i: integer; // currSession: TROSession; begin lArray := SessionManager.GetAllSessions(fApplicationID_Ansi); try for I := 0 to lArray.Count - 1 do begin { currSession := FindSession(lArray.Items[i],False); if CheckSessionIsExpired(currSession) then Continue; } Dest.Add(lArray.Items[i]); end; finally lArray.Free; end; end; function TROOlympiaSessionManager.DoGetSessionCount: integer; begin result := SessionManager.GetSessionCount(fApplicationID_Ansi); end; procedure TROOlympiaSessionManager.DoReleaseSession( aSession: TROSession; NewSession: boolean); var data : Binary; begin data := Binary.Create; try aSession.SaveToStream(data, TRUE); if NewSession then SessionManager.CreateSession(GUIDToAnsiString(aSession.SessionID),fApplicationID_Ansi, data) else SessionManager.UpdateSession(GUIDToAnsiString(aSession.SessionID), data); aSession.Free(); finally data.Free; end; end; function TROOlympiaSessionManager.GetChannel: TROTransportChannel; begin Result := FEventReceiver.Channel; end; function TROOlympiaSessionManager.GetSessionManager: IOlympiaSessionManager; begin CheckProperties; result := CoOlympia.Create(TROBinMessage.CreateRefCountedClone(fBINMessage), FEventReceiver.Channel); end; procedure TROOlympiaSessionManager.Loaded; begin inherited; if fStreamedActive then Active:=True; end; procedure TROOlympiaSessionManager.Notification( AComponent: TComponent; Operation: TOperation); begin if (Operation = opRemove) and (AComponent=FEventReceiver.Channel) then FEventReceiver.Channel := NIL; inherited; end; procedure TROOlympiaSessionManager.SessionsExpired( const aExpiredSessionIDs: GuidArray); var i: integer; begin if Assigned(OnSessionDeleted) then for i := 0 to aExpiredSessionIDs.Count - 1 do if Assigned(OnSessionDeleted) then OnSessionDeleted(StringToGUID(aExpiredSessionIDs.Items[i]), True); end; procedure TROOlympiaSessionManager.SetActive(const Value: Boolean); begin if (csLoading in ComponentState) then begin fStreamedActive := Value end else begin if FActive = Value then exit; FActive := Value; if csDesigning in ComponentState then exit; if FActive then begin CheckProperties; if IsEqualGUID(EmptyGUID, fBINMessage.ClientID) then fBINMessage.ClientID := NewGuid; SessionManager.RegisterForSessionEvents(fApplicationID_Ansi); FEventReceiver.Channel := Channel; FEventReceiver.Message := fBINMessage; FEventReceiver.SynchronizeInvoke := false; FEventReceiver.ServiceName := 'Olympia'; FEventReceiver.ServersideRegisterEvents := false; FEventReceiver.RegisterEventHandler('OlympiaSessionManagerEvents', self); FEventReceiver.Activate; end else begin FEventReceiver.UnregisterEventHandler('OlympiaSessionManagerEvents'); FEventReceiver.Deactivate; end; end; end; procedure TROOlympiaSessionManager.SetApplicationID(const Value: TGUID); begin fApplicationID_Ansi:= GUIDToAnsiString(Value); fApplicationID := Value; if FEventReceiver.Active then SessionManager.RegisterForSessionEvents(fApplicationID_Ansi); end; procedure TROOlympiaSessionManager.SetChannel( const Value: TROTransportChannel); begin if (FEventReceiver.Channel <> Value) then begin if (FEventReceiver.Channel <> NIL) then FEventReceiver.Channel.RORemoveFreeNotification(Self); FEventReceiver.Channel := Value; if (FEventReceiver.Channel <> NIL) then FEventReceiver.Channel.ROFreeNotification(Self); end; end; end.