管理靠一单例TDSSessionManager来管理。对于目前说到TDSTCPServerTransport,建立的的Session为TDSTCPSession,它是TDSSession的子类。
Session在开始连接后,就创建了,再连接断开后消亡。
TDSSession = class
private
FStartDateTime: TDateTime; /// creation timestamp
FDuration: Integer; /// in miliseconds, 0 for infinite (default)
FStatus: TDSSessionStatus; /// default idle
FLastActivity: Cardinal; /// timestamp of the last activity on this session
FUserName: String; /// user name that was authenticated with this session
FSessionName: String; /// session name, may be internally generated, exposed to 3rd party
FMetaData: TDictionary; /// map of metadata stored in the session
FMetaObjects: TDictionary; /// map of objects stored in the session
FUserRoles: TStrings; /// user roles defined through authentication
FCache: TDSSessionCache;
FLastResultStream: TObject; /// Allow any object which owns a stream, or the stream itself, to be stored here
FCreator: TObject; /// Creator of the session object reference
可以看出,Session可以用存储了很多东西 。用得多的是FMetaData与FMetaObjects对于字符串,PutData放进去,GetData取出来;对于Object,PutObject放进去,GetObject取出来。
使用方法为
TDSSessionManager.GetThreadSession.PutData('userid', userId);
userId := TDSSessionManager.GetThreadSession.GetData('userid');
另外,放入FMetaObjects的Object,Session的Free时,会自动帮忙Free,所以不必自己去Free的。关于Session的超时,
这里自然就想到了TDSTCPServerTransport的KeepAliveInterval和KeepAliveTime属性,这两个属性,其实和Session管理没关系。
跟踪代码,这两个属性的反应在IdStackWindows.pas的
procedure TIdStackWindows.SetKeepAliveValues(ASocket: TIdStackSocketHandle;
const AEnabled: Boolean; const ATimeMS, AInterval: Integer);
var
ka: tcp_keepalive;
Bytes: DWORD;
begin
// SIO_KEEPALIVE_VALS is supported on Win2K+ only
if AEnabled and (Win32MajorVersion >= 5) then
begin
ka.onoff := 1;
ka.keepalivetime := ATimeMS;
ka.keepaliveinterval := AInterval;
WSAIoctl(ASocket, SIO_KEEPALIVE_VALS, @ka, SizeOf(ka), nil, 0, @Bytes, nil, nil);
end else begin
SetSocketOption(ASocket, Id_SOL_SOCKET, Id_SO_KEEPALIVE, iif(AEnabled, 1, 0));
end;
end;
里,其实就是简单设置了一下socket fd的属性,所以说TDSSessionManager毛关系都没有。另外, KeepAliveTime默认值为300000,也就是300秒,KeepAliveInterval默认值为100,这是啥意思呢。KeepAliveTime是sockfd最后一次通讯后,等待了的时间,如果300秒内没通讯,socket栈就自己开始发送心跳探测了,如果每次都没回答,就每隔KeepAliveInterval毫秒问一次。至于问多少次认为是网络断开了,根据Windows OS来定的,windows 2000, 2003是5次,vista以后问10次。也就是说,根据TDSTCPServerTransport的默认设定,网络断了,在win7上,要300+0.1*10,也即是301秒才知道网络断了。
OS的系统设定更长,没数据通讯后2小时才开始探测,每隔1秒探测一回。
SIO_KEEPALIVE_VALS值Windows的OS独有的,Unix还是用SO_KEEPALIVE。
跑题远了,回到正题。如何监控Session呢,TDSSessionManager提供了方法给你插入监听事件。
上代码
var
event: TDSSessionEvent;
initialization
event := procedure(Sender: TObject;
const EventType: TDSSessionEventType;
const Session: TDSSession)
begin
case EventType of
SessionCreate:
begin
LogInfo('SessionCreate');
LogInfo(Format('SessionName=%s', [Session.SessionName]));
end;
SessionClose:
begin
LogInfo('SessionClose');
LogInfo(Format('SessionName=%s', [Session.SessionName]));
end;
end;
end;
TDSSessionManager.Instance.AddSessionEvent(event);
finalization
TDSSessionManager.Instance.RemoveSessionEvent(event);
这样就可以了,有多少事件都可以插入监听。
没有评论:
发表评论