HTTP, durumsuz (stateless) bir protokoldür (en azından HTTP 1.1'e kadar), bu yüzden istemci bir dosya ister, sunucu bir yanıt gönderir ve bağlantı kapatılır (bağlantının hemen kapatılmaması için keep-alive'ı etkinleştirebilirsiniz, ancak bu, bu makalenin kapsamı dışındadır). Oturumlar, istemci hakkında bilgi saklamanıza olanak tanır; bu, örneğin bir istemci oturum açması sırasında kullanılabilir. Herhangi bir benzersiz oturum ID'si kullanabilir, birinin zaten var olup olmadığını görmek için oturum listesini arayabilir ve yoksa yeni bir oturum oluşturabilirsiniz. Bir oturum, bir etkinlik dışı süreden sonra veya istemci oturumu kapattıktan sonra manuel olarak yok edilebilir.
TsgcWebSocketHTTPServer'da sunucu bileşenindeki oturumları etkinleştiren/devre dışı bırakan bazı özellikler vardır. En önemlileri şunlardır:
| Özellik | Açıklama |
| SessionState | Bu, Oturumları kullanmak için etkinleştirilmesi gereken ilk özelliktir. Bu özellik etkinleştirilmeden oturumlar çalışmaz |
|
SessionTimeout |
Burada bir oturumun etkin kalacağı maksimum süre için sıfırdan büyük bir değer (milisaniye cinsinden) ayarlamalısınız. |
| AutoStartSession | Oturumlar otomatik olarak (AutoStartSession = true) veya manuel olarak (AutoStartSession = false) oluşturulabilir. Oturumlar otomatik olarak oluşturulursa, sunucu, saklanan etkin bir oturum olup olmadığını kontrol etmek için benzersiz bir tanımlayıcı olarak RemoteIP'yi kullanır. |
| SessionClass | İsteğe bağlı. Sunucunun yeni bir oturum oluştururken kullandığı sınıf. Her oturumun içinde kendi verilerinizi saklamak için bunu kendi TIdHTTPSession alt sınıfınıza ayarlayın. Sunucu etkinleştirilmeden önce ayarlanmalıdır. |
| SessionList | Etkin oturumları tutan liste. Kodla oturum aramak, oluşturmak veya kaldırmak için okuyun. Oturumların nerede saklandığı üzerinde tam kontrole ihtiyaç duyarsanız kendi listenizi de atayabilirsiniz. Sunucu etkinleştirilmeden önce atanmalıdır. |
TsgcWebSocketHTTPServer1.SessionState := True;
TsgcWebSocketHTTPServer1.SessionTimeout := 600000;
TsgcWebSocketHTTPServer1.AutoStartSession := False;
Yeni bir oturum oluşturmak için, benzersiz olan yeni bir session ID oluşturmanız gerekir. Herhangi bir değer kullanabilirsiniz. Örnek: istemci kimlik doğruluyorsa, session ID olarak user + password + remoteip kullanabilirsiniz.
Ardından, zaten var olup olmadığını kontrol etmek için oturum listesini arayın. Yoksa, yeni bir tane oluşturun.
Yeni bir oturum oluşturulduğunda OnSessionStart olayı çağrılır ve oturum kapatıldığında, OnSessionEnd olayı tetiklenir.
procedure OnCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
AResponseInfo: TIdHTTPResponseInfo);
var
vID: String;
oSession: TIdHTTPSession;
begin
if ARequestInfo.Document = '/' then
AResponseInfo.ServeFile(AContext, 'yourpathhere\index.html')
else
begin
// check if user is valid
if not ((ARequestInfo.AuthUsername = 'user') and (ARequestInfo.AuthPassword = 'pass')) then
AResponseInfo.AuthRealm := 'Authenticate'
else
begin
// create a new session id with authentication data
vID := ARequestInfo.AuthUsername + '_' + ARequestInfo.AuthPassword + '_' + ARequestInfo.RemoteIP;
// search session
oSession := TsgcWebSocketHTTPServer1.SessionList.GetSession(vID, ARequestInfo.RemoteIP);
// create new session if not exists
if not Assigned(oSession) then
oSession := TsgcWebSocketHTTPServer1.SessionList.CreateSession(ARequestInfo.RemoteIP, vID);
AResponseInfo.ContentText := '<html><head></head><body>Authenticated</body></html>';
AResponseInfo.ResponseNo := 200;
end;
end;
end;
Bir oturum var olduğunda, sunucu onu oturum çerezini taşıyan her isteğe ekler. Bunu, isteğin oturumu olmadığında nil olan ARequestInfo.Session üzerinden okuyun.
procedure OnCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
AResponseInfo: TIdHTTPResponseInfo);
begin
if Assigned(ARequestInfo.Session) then
begin
// Content is a TStrings you can use to store your own values
ARequestInfo.Session.Content.Values['visits'] :=
IntToStr(StrToIntDef(ARequestInfo.Session.Content.Values['visits'], 0) + 1);
AResponseInfo.ContentText := 'Session ' + ARequestInfo.Session.SessionID +
' visits: ' + ARequestInfo.Session.Content.Values['visits'];
end
else
AResponseInfo.ContentText := 'No session';
end;
Her oturum içinde kendi alanlarınızı tutmak istiyorsanız, Content dize listesini kullanmak yerine, TIdHTTPSession'ın bir alt sınıfını oluşturun ve sunucuya bunu SessionClass özelliği aracılığıyla kullanmasını söyleyin. Bunu, sunucu etkinleştirilmeden önce ayarlayın.
Sunucu geri kalan her şeyi üstlenmeye devam eder: benzersiz oturum kimliğini üretir, oturum çerezini gönderir, SessionTimeout değerini uygular ve eskimiş oturumları kaldırır. Oturum oluşturulduğunda kendi alanlarınızı ilklendirmek istiyorsanız sanal yapıcı CreateInitialized yöntemini geçersiz kılın.
type
TMySession = class(TIdHTTPSession)
private
FUserName: String;
FLoginTime: TDateTime;
public
constructor CreateInitialized(AOwner: TIdHTTPCustomSessionList;
const SessionID, RemoteIP: string); override;
property UserName: String read FUserName write FUserName;
property LoginTime: TDateTime read FLoginTime write FLoginTime;
end;
constructor TMySession.CreateInitialized(AOwner: TIdHTTPCustomSessionList;
const SessionID, RemoteIP: string);
begin
inherited CreateInitialized(AOwner, SessionID, RemoteIP);
FLoginTime := Now;
end;
// configure the server before it starts
TsgcWebSocketHTTPServer1.SessionState := True;
TsgcWebSocketHTTPServer1.SessionTimeout := 600000;
TsgcWebSocketHTTPServer1.SessionClass := TMySession;
TsgcWebSocketHTTPServer1.Active := True;
// and read it back in any request
procedure OnCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
AResponseInfo: TIdHTTPResponseInfo);
begin
if ARequestInfo.Session is TMySession then
AResponseInfo.ContentText := TMySession(ARequestInfo.Session).UserName;
end;
Oturumların nasıl saklandığı üzerinde tam denetime ihtiyacınız varsa, örneğin onları bir veritabanında tutmak veya birden çok sunucu arasında paylaşmak için, sunucu etkinleştirilmeden önce kendi listenizi SessionList özelliğine atayın. TIdHTTPDefaultSessionList'ten türetin ve sanal CreateSession yöntemini override edin. Sunucu bunu dahili olarak CreateUniqueSession'dan çağırır, böylece benzersiz oturum kimliği yine de sizin için üretilir.
Kendi SessionList'inizi atadığınızda, SessionClass özelliği artık uygulanmaz, çünkü hangi sınıfın oluşturulacağına listeniz karar verir.
type
TMySessionList = class(TIdHTTPDefaultSessionList)
public
function CreateSession(const RemoteIP, SessionID: string)
: TIdHTTPSession; override;
end;
function TMySessionList.CreateSession(const RemoteIP, SessionID: string)
: TIdHTTPSession;
begin
Result := TMySession.CreateInitialized(Self, SessionID, RemoteIP);
SessionList.Add(Result);
end;
// assign it before the server starts
TsgcWebSocketHTTPServer1.SessionList := TMySessionList.Create(nil);
TsgcWebSocketHTTPServer1.Active := True;
OnCreateSession olayı, kendi oturum örneğinizi döndürmenize olanak tanır, ancak ona bir oturum kimliği atamaz. Oturumu düz bir yapıcı ile oluşturursanız, oturum kimliği ve oturum çerezi boş kalır ve oturum bir sonraki istekte bir daha bulunamaz. Bunun yerine, tüm bunları sizin için halleden ve daha basit olan SessionClass'ı kullanın.
Ayrıca, OnCreateSession içinde SessionList.CreateUniqueSession'ı çağırmayın. Bu yöntem yeni oturumu zaten listeye ekler ve işleyiciniz döndüğünde sunucu onu tekrar ekler, bu nedenle aynı oturum listede iki kez sonuçlanır.