TsgcWebSocketServer › Ereignisse › OnQueueDrained
Wird ausgelöst, wenn die ausgehende Warteschlange einer Client-Verbindung von gefüllt auf leer wechselt.
property OnQueueDrained: TsgcWSQueueDrainedEvent;
// TsgcWSQueueDrainedEvent = procedure(Connection: TsgcWSConnection) of object
—
Wird nur ausgelöst, wenn die Nachrichten-Warteschlange für die betroffene Verbindung aktiv ist, das heißt wenn QueueOptions.Text.Level, QueueOptions.Binary.Level oder QueueOptions.Ping.Level auf etwas anderes als qmNone gesetzt ist. Ohne Warteschlange gibt es nichts zu leeren und das Ereignis wird nie ausgelöst.
Der Handler läuft inline im Verbindungs-Thread und wird bewusst nicht über NotifyEvents gemarshallt, anders als jedes andere Ereignis dieser Komponente, und darf deshalb die Benutzeroberfläche nicht anfassen. Die Abweichung ist beabsichtigt. Der ganze Wert des Ereignisses liegt darin, dass es genau an dieser Stelle der Verbindungsschleife läuft, direkt nachdem die Warteschlange geleert wurde und vor dem nächsten Lesevorgang, während der Socket noch untätig ist, sodass die Anwendung das nächste Kontingent ohne Wartezeit vergeben kann. Ein Marshalling in den Haupt-Thread würde das zunichtemachen. Jede Aktualisierung von Formularen, Grids oder Labels muss die Anwendung selbst marshallen, mit TThread.Queue, TThread.Synchronize oder einer an den Haupt-Thread gesendeten Nachricht.
Ausnahmen, die innerhalb des Handlers ausgelöst werden, werden abgefangen und verworfen, damit das Leeren immer abgeschlossen wird. Ein Handler, der fehlschlägt, tut dies still. Umschließen Sie den Rumpf daher mit einem eigenen try..except-Block, wenn ein Fehler gemeldet werden muss.
Das Ereignis wird einmal pro Übergang von nicht leer zu leer ausgelöst, nicht einmal pro Durchlauf der Verbindungsschleife. Es ist kein Signal dafür, dass ein Burst beendet ist. Wenn das Leeren mit einem langsamen Produzenten Schritt hält, kann jede einzelne Nachricht ihr eigenes Ereignis auslösen, weil jede Nachricht hinausgeschrieben wird, bevor die nächste eingereiht wird. Was das Ereignis aussagt, ist, dass die Warteschlange dieser Verbindung genau jetzt leer ist, mehr nicht.
Der typische Einsatz ist Flusskontrolle. Wenn der Server Massendaten zwischen Clients weiterleitet, verwenden Sie das Ereignis, um einem sendenden Client mitzuteilen, dass er weitere Daten senden darf. Kombinieren Sie es mit der Eigenschaft PendingCount von TsgcWSConnection, die meldet, wie viele Nachrichten für diese Verbindung noch eingereiht sind, um ein Kreditfenster statt eines Stop-and-Wait-Austauschs zu betreiben.
Der verwaltete .NET-Port löst dasselbe Ereignis mit derselben Bedeutung aus. Der einzige Unterschied ist, wie oft es eintrifft. Das Leeren in Delphi läuft einmal pro Durchlauf der Verbindungsschleife, die Options.ReadTimeOut Millisekunden auseinanderliegt und standardmäßig 10 beträgt, sodass ein langsamer, dünner Nachrichtenstrom zu wenigen Ereignissen zusammengefasst wird. Das verwaltete Leeren ist ereignisgesteuert und derselbe Strom kann mehr Ereignisse auslösen. Bursts verhalten sich auf beiden identisch.
procedure OnQueueDrained(Connection: TsgcWSConnection);
begin
// runs on the connection thread, do not touch the user interface here
Connection.WriteData('credit 64');
end;