TsgcWebSocketHTTPServer › Zdarzenia › OnQueueDrained
Uruchamiane, gdy kolejka wychodząca połączenia WebSocket przechodzi ze stanu z wiadomościami do stanu pustego.
property OnQueueDrained: TsgcWSQueueDrainedEvent;
// TsgcWSQueueDrainedEvent = procedure(Connection: TsgcWSConnection) of object
—
Uruchamiane tylko wtedy, gdy kolejkowanie wiadomości jest aktywne dla danego połączenia, to znaczy gdy QueueOptions.Text.Level, QueueOptions.Binary.Level lub QueueOptions.Ping.Level ma wartość inną niż qmNone. Bez kolejki nie ma czego opróżniać i zdarzenie nigdy nie jest wywoływane. Zwykłe żądania HTTP nie są kolejkowane, więc zgłaszają je tylko połączenia WebSocket.
Procedura obsługi wykonuje się bezpośrednio w wątku połączenia i celowo nie jest przekazywana przez NotifyEvents, w przeciwieństwie do wszystkich pozostałych zdarzeń tego komponentu, więc nie może dotykać interfejsu użytkownika. To odstępstwo jest zamierzone. Cała wartość tego zdarzenia polega na tym, że wykonuje się dokładnie w tym punkcie pętli połączenia, zaraz po opróżnieniu kolejki i przed kolejnym odczytem, gdy gniazdo jest jeszcze bezczynne, dzięki czemu aplikacja może przyznać następny kredyt bez czekania. Przekazanie go do wątku głównego zniweczyłoby tę korzyść. Każdą aktualizację formularza, siatki czy etykiety aplikacja musi przekazać sama, za pomocą TThread.Queue, TThread.Synchronize lub komunikatu wysłanego do wątku głównego.
Wyjątki zgłoszone wewnątrz procedury obsługi są przechwytywane i pomijane, tak aby opróżnianie kolejki zawsze zostało zakończone. Procedura obsługi, która zawiedzie, robi to po cichu, dlatego opakuj jej treść we własny blok try..except, gdy awaria musi zostać zgłoszona.
Zdarzenie jest wywoływane raz na każde przejście ze stanu niepustego do pustego, a nie raz na każdy przebieg pętli połączenia. Nie jest to sygnał, że seria wiadomości się zakończyła. Jeśli opróżnianie nadąża za powolnym producentem, każda pojedyncza wiadomość może wywołać własne zdarzenie, ponieważ każda wiadomość jest wysyłana, zanim kolejna trafi do kolejki. Zdarzenie stwierdza jedynie, że kolejka tego połączenia jest w tej chwili pusta, nic więcej.
Typowym zastosowaniem jest kontrola przepływu. Gdy serwer przekazuje duże ilości danych między klientami, użyj tego zdarzenia, aby powiadomić wysyłającego klienta, że może wysłać więcej. Połącz je z właściwością PendingCount klasy TsgcWSConnection, która podaje, ile wiadomości nadal czeka w kolejce tego połączenia, aby zrealizować okno kredytowe zamiast wymiany typu stop-and-wait.
Zarządzany port .NET zgłasza to samo zdarzenie o tym samym znaczeniu. Jedyna różnica dotyczy częstotliwości jego występowania. Opróżnianie kolejki w Delphi wykonuje się raz na przebieg pętli połączenia, czyli co Options.ReadTimeOut milisekund, domyślnie co 10, więc powolny strumyk wiadomości jest łączony w niewiele zdarzeń. Opróżnianie w wersji zarządzanej jest sterowane zdarzeniami i ten sam strumyk może wywołać więcej zdarzeń. Serie wiadomości zachowują się identycznie w obu wersjach.
procedure OnQueueDrained(Connection: TsgcWSConnection);
begin
// runs on the connection thread, do not touch the user interface here
Connection.WriteData('credit 64');
end;