TsgcWebSocketHTTPServer | Sessions

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.

 

Yapılandırma

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. Kendi verilerinizi her oturumun içinde saklamak için bunu kendi TIdHTTPSession torununuza ayarlayın. Sunucu etkinleştirilmeden önce ayarlanmalıdır.
SessionList Etkin oturumları tutan liste. Oturumları kodla aramak, oluşturmak veya kaldırmak için okuyun. Oturumların nerede saklandığı üzerinde tam denetime ihtiyaç duyarsanız kendi listenizi de atayabilirsiniz. Sunucu etkinleştirilmeden önce atanmalıdır.

 

 


TsgcWebSocketHTTPServer1.SessionState := True;
TsgcWebSocketHTTPServer1.SessionTimeout := 600000;
TsgcWebSocketHTTPServer1.AutoStartSession := False;

 

Create Session

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;

Geçerli Oturumu Okuyun

Bir oturum var olduğunda, sunucu bunu oturum çerezini taşıyan her isteğe iliştirir. Bunu, isteğin oturumu olmadığında nil olan ARequestInfo.Session öğesinden 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;

Kendi Oturum Sınıfınızı Kullanın

Content dize listesini kullanmak yerine kendi alanlarınızı her oturumun içinde tutmak istiyorsanız, TIdHTTPSession sınıfının bir torununu oluşturun ve SessionClass özelliği aracılığıyla sunucuya bunu kullanmasını söyleyin. Bunu sunucu etkinleştirilmeden önce ayarlayın.

Sunucu diğer her şeyle ilgilenmeye devam eder: benzersiz oturum ID'sini oluşturur, oturum çerezini gönderir, SessionTimeout değerini uygular ve eski oturumları kaldırır. Oturum oluşturulduğunda kendi alanlarınızı ilklendirmek istiyorsanız, sanal yapıcı CreateInitialized öğesini 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;

Kendi Oturum Listenizi Kullanın

Oturumların nasıl saklandığı üzerinde tam denetime ihtiyaç duyarsanız, örneğin bunları bir veritabanında tutmak veya birkaç sunucu arasında paylaşmak için, sunucu etkinleştirilmeden önce kendi listenizi SessionList özelliğine atayın. TIdHTTPDefaultSessionList sınıfından türetin ve sanal CreateSession yöntemini geçersiz kılın. Sunucu bunu CreateUniqueSession içinden dahili olarak çağırır, bu yüzden benzersiz oturum ID'si yine sizin için üretilir.

Kendi SessionList değerinizi atadığınızda, SessionClass özelliği artık geçerli olmaz, çü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 Hakkında Bir Not

OnCreateSession olayı bir oturum örneğini kendiniz döndürmenize izin verir, ancak buna bir oturum ID'si atamaz. Oturumu düz bir yapıcıyla oluşturursanız, oturum ID'si ve oturum çerezi boş olur ve oturum sonraki istekte bir daha asla bulunamaz. Bunun yerine, daha basit olan ve tüm bunları sizin için halleden SessionClass özelliğini kullanın.

Ayrıca, OnCreateSession içinde SessionList.CreateUniqueSession öğesini çağırmayın. O yöntem, yeni oturumu listeye zaten ekler ve işleyiciniz döndüğünde sunucu bunu tekrar ekler, bu yüzden aynı oturum listede iki kez yer alır.