TsgcWebTransportSession › Ereignisse › OnClose
Wird ausgelöst, wenn Close auf der Sitzung aufgerufen wird. In Delphi und C++Builder geschieht das immer nur, weil Ihr eigener Code es aufgerufen hat.
property OnClose: TsgcWebTransportNotifyEvent read FOnClose write FOnClose;
// event type
TsgcWebTransportNotifyEvent = procedure(Sender: TObject) of object;
// handler signature
procedure MySessionClose(Sender: TObject);
| Name | Typ | Beschreibung |
|---|---|---|
Sender | TObject | Die TsgcWebTransportSession, die geschlossen wird. Casten Sie sie, wenn Sie die SessionId oder die Streams der Sitzung benötigen. |
Der C#-Handler erhält zusätzlich einen EventArgs-Parameter, der immer EventArgs.Empty ist und keine Informationen enthält.
Nicht zugewiesen. Wenn kein Handler zugewiesen ist, markiert Close die Sitzung dennoch als geschlossen und schließt die noch darauf offenen Streams.
Wann es ausgelöst wird. Nur von Close, und Close wird weder vom Delphi- noch vom C++Builder-HTTP/3-Client oder -Server aufgerufen. In der Praxis wird dieses Ereignis also genau dann ausgelöst, wenn Ihr eigener Code oSession.Close aufruft. Es ist ein lokales Signal, das Sie selbst senden, keine Benachrichtigung aus dem Netzwerk. Nichts löst es aus, wenn der Peer verschwindet, wenn die QUIC-Verbindung abbricht oder wenn die Sitzung freigegeben wird.
Wenn Sie wissen müssen, dass eine Sitzung wirklich beendet wurde, beobachten Sie stattdessen die verbindungsbezogenen Ereignisse des Clients oder verfolgen Sie den Verlust Ihrer Streams.
Die Sitzung ist innerhalb des Handlers weiterhin vollständig gültig. Close gibt die Sitzung nicht frei und meldet sie nicht ab, Sie können daher gefahrlos SessionId lesen oder eine beliebige Methode aufrufen. Die Streams der Sitzung wurden allerdings bereits geschlossen, wenn dieses Ereignis ausgeführt wird, jeder ihrer OnClose-Handler wurde also ausgelöst und StreamCount ist 0. Die Stream-Objekte selbst bleiben aktiv und lesbar, bis die Sitzung zerstört wird. Betrachten Sie die Sitzung als beendet, sobald Sie sie geschlossen haben, und schreiben Sie nicht mehr in sie.
Close ist gegen wiederholte Aufrufe geschützt, daher wird dieses Ereignis höchstens einmal pro Sitzung ausgelöst, selbst wenn Close innerhalb des Handlers erneut aufgerufen wird.
Threading. Das Ereignis läuft auf dem Thread, der Close aufgerufen hat, ohne eigene Synchronisierung. Ist das ein Hintergrundthread und greift Ihr Handler auf die Benutzeroberfläche zu, marshallen Sie mit TThread.Synchronize oder TThread.Queue.
.NET-Unterschied, und zwar ein echter. Auf dem verwalteten Stack ruft der Client Close tatsächlich für Sie auf. Eine Hintergrundaufgabe leert den CONNECT-Stream, und wenn der Server ihn schließt oder verwirft, entfernt diese Aufgabe die Sitzung aus der Registry und ruft Close auf. Unter .NET dient OnClose daher zugleich als echte Benachrichtigung über die Trennung durch den Peer, und es wird in einem Thread-Pool-Thread ausgelöst. Code, der gegen das Delphi-Verhalten geschrieben ist, sollte nicht annehmen, dass das Ereignis von selbst eintrifft, und Code, der gegen das .NET-Verhalten geschrieben ist, sollte nicht annehmen, dass es das nicht tut. Was Close selbst tut, ist auf jedem Stack gleich: Es schließt die offenen Streams der Sitzung, bevor dieses Ereignis ausgelöst wird, und es ist gegen wiederholte Aufrufe abgesichert.
// Assign right after the session is created, on either side
procedure TfrmClient.btnConnectClick(Sender: TObject);
begin
FSession := FClient.WebTransportConnect('https://127.0.0.1:4433/echo');
if Assigned(FSession) then
FSession.OnClose := OnSessionClose;
end;
procedure TfrmClient.OnSessionClose(Sender: TObject);
var
oSession: TsgcWebTransportSession;
begin
oSession := TsgcWebTransportSession(Sender);
// The session is still valid here, so its state can be inspected
memoLog.Lines.Add(Format('session %d closed after %d streams',
[oSession.SessionId, oSession.StreamCount]));
// Release only OUR state; the session is owned by the client
tmrPump.Enabled := False;
FStream := nil;
end;