There is something wrong with DataSnap at least in Delphi 10 or I did something wrong. Anyway, when client application becomes to be frozen (f.e. long time running SQL query or becomes to be frozen somehow in another way or client application did not ask anything from the DataSnap for awhile), DatSnap stopped to create new instance for other client, after DataSnap ran TDSSessionManager.Instance.CloseSession(ASession.SessionName);.
Controls used in DataSnap server side application: DSServer and DSHTTPService. Client application communicates via http(s).
In Server side DataModuleCreate set how long session will live in an inactive state:
TDSSessionManager.Instance.AddSessionEvent(
procedure(Sender: TObject;
const EventType: TDSSessionEventType;
const Session: TDSSession)
begin
case EventType of
{The provided Session was just created.}
SessionCreate: Session.LifeDuration := 10000000; // less than 3 hours
{The provided Session has just been closed, either intentionally or it has expired.}
SessionClose: ;
end;
end);
Define how to mark that session is active:
function <>.DSServerTrace(TraceInfo: TDBXTraceInfo): CBRType;
begin
if TraceInfo.TraceFlag in [TDBXTraceFlags.Execute, TDBXTraceFlags.Command, TDBXTraceFlags.Transact, TDBXTraceFlags.Reader, TDBXTraceFlags.Driver, TDBXTraceFlags.Custom] then // mark session as an active
TDSSessionManager.Instance.GetThreadSession.MarkActivity;
Result := cbrUSEDEF;
end;
In DSServerConnect(DSConnectEventObject: TDSConnectEventObject); run procedure below:
procedure clearInactiveSessions();
var
sl: TStringList;
_Session: TDSSession;
i: Integer;
begin
sl := TStringList.Create;
try
TDSSessionManager.Instance.ForEachSession(
procedure(const ASession: TDSSession)
begin
// different session
if (ASession.SessionName <> TDSSessionManager.Instance.GetThreadSession.SessionName)
and(
(not ASession.IsValid)
or
(ASession.ElapsedSinceLastActvity > UINT(ASession.LifeDuration))
)
then
begin
//TDSSessionManager.Instance.CloseSession(ASession.SessionName); // ATTENTION: Causes a freezing of application
TDBXScheduler.Instance.CancelEvent(ASession.Id);
// add removed session from the SessionManager to the list
sl.AddObject(ASession.SessionName, TDSSessionManager.Instance.RemoveSession(ASession.SessionName));
end;
end
);
for i := 0 to sl.Count - 1 do
begin
_Session := TDSSession(sl.Objects[i]);
if Assigned(_Session) then
FreeAndNil(_Session);
end;
finally
FreeAndNil(sl);
end;
end;
So above procedure shall be ran, when new client trying to connect to the DataSnap.
Normally, TDSSessionManager.Instance.CloseSession(ASession.SessionName); should work fine, but for some reason did not.
As result, frozen or inactive client application did not get any respond that its connection was closed, but session becomes properly closed. Client can kill its process and DataSnap still continue working.
Probably in Delphi 10.3.x it is fixed, will check somewhen.
Немає коментарів:
Дописати коментар