TsgcWebSocketClient › Événements › OnQueueDrained
Se déclenche lorsque la file d'attente de messages sortants passe de l'état non vide à l'état vide.
property OnQueueDrained: TsgcWSQueueDrainedEvent;
// TsgcWSQueueDrainedEvent = procedure(Connection: TsgcWSConnection) of object
—
Ne se déclenche que lorsque la mise en file d'attente des messages est active, c'est-à-dire lorsque QueueOptions.Text.Level, QueueOptions.Binary.Level ou QueueOptions.Ping.Level a une valeur autre que qmNone. Sans file d'attente, il n'y a rien à vider et l'événement n'est jamais déclenché.
Le gestionnaire s'exécute en ligne sur le thread de connexion et n'est délibérément pas marshalé via NotifyEvents, contrairement à tous les autres événements de ce composant, il ne doit donc pas toucher à l'interface utilisateur. Cet écart est intentionnel. Tout l'intérêt de l'événement est qu'il s'exécute à ce point précis de la boucle de connexion, juste après que la file d'attente a été vidée et avant la lecture suivante, alors que le socket est encore inactif, de sorte que l'application peut libérer le fragment suivant sans attendre. Le marshaler vers le thread principal détruirait cet avantage. Toute mise à jour d'une fiche, d'une grille ou d'un libellé doit être marshalée par l'application elle-même, avec TThread.Queue, TThread.Synchronize ou un message posté au thread principal.
Les exceptions levées à l'intérieur du gestionnaire sont interceptées et ignorées afin que la vidange se termine toujours. Un gestionnaire qui échoue le fait silencieusement, encadrez donc son corps dans son propre bloc try..except lorsqu'un échec doit être signalé.
L'événement se déclenche une fois par transition de l'état non vide vers l'état vide, et non une fois par passage de la boucle de connexion. Ce n'est pas un signal indiquant qu'une rafale est terminée. Si la vidange suit le rythme d'un producteur lent, chaque message peut déclencher son propre événement, car chaque message est écrit avant que le suivant ne soit mis en file d'attente. Ce que l'événement indique, c'est que la file d'attente de cette connexion est vide à cet instant, rien de plus.
L'usage typique est le contrôle de flux. Lorsque le client diffuse des données en masse, utilisez l'événement pour libérer le fragment suivant afin que le producteur suive la vitesse du socket au lieu de saturer la mémoire. Associez-le à la propriété PendingCount de TsgcWSConnection, qui indique combien de messages sont encore en file d'attente pour la connexion, afin de mettre en place une fenêtre de crédit plutôt qu'un échange en mode arrêt et attente.
Le portage .NET managé déclenche le même événement avec la même signification. La seule différence est la fréquence à laquelle il arrive. La vidange Delphi s'exécute une fois par passage de la boucle de connexion, soit toutes les Options.ReadTimeOut millisecondes, 10 par défaut, de sorte qu'un filet lent de messages est regroupé en peu d'événements. La vidange managée est pilotée par les événements et le même filet peut en déclencher davantage. Les rafales se comportent de façon identique dans les deux cas.
procedure OnQueueDrained(Connection: TsgcWSConnection);
begin
// runs on the connection thread, do not touch the user interface here
Connection.WriteData(GetNextChunk);
end;