TsgcWebSocketHTTPServer › Olaylar › OnQueueDrained

OnQueueDrained Olay

Bir WebSocket bağlantısının giden kuyruğu, ileti tutar durumdan boş duruma geçtiğinde tetiklenir.

Sözdizimi

property OnQueueDrained: TsgcWSQueueDrainedEvent;
// TsgcWSQueueDrainedEvent = procedure(Connection: TsgcWSConnection) of object

Varsayılan Değer

—

Remarks

Yalnızca etkilenen bağlantı için ileti kuyruklama etkinken tetiklenir, yani QueueOptions.Text.Level, QueueOptions.Binary.Level veya QueueOptions.Ping.Level qmNone dışında bir değere ayarlandığında. Kuyruk yoksa boşaltılacak bir şey de yoktur ve varsayılan qdmTransition modunda olay hiçbir zaman tetiklenmez. Düz HTTP istekleri kuyruğa alınmaz, bu nedenle olayı yalnızca WebSocket bağlantıları tetikler.

İşleyici, bağlantı iş parçacığı üzerinde satır içi olarak çalışır ve bu bileşenin diğer tüm olaylarının aksine kasıtlı olarak NotifyEvents üzerinden aktarılmaz; bu nedenle kullanıcı arayüzüne dokunmamalıdır. Bu sapma bilinçlidir. Olayın tüm değeri, bağlantı döngüsünün tam o noktasında, kuyruk boşaldıktan hemen sonra ve bir sonraki okumadan önce, soket hâlâ boştayken çalışmasıdır; böylece uygulama beklemeden bir sonraki krediyi verebilir. Olayı ana iş parçacığına aktarmak bunu ortadan kaldırırdı. Herhangi bir form, ızgara veya etiket güncellemesinin uygulamanın kendisi tarafından TThread.Queue, TThread.Synchronize veya ana iş parçacığına gönderilen bir mesajla aktarılması gerekir.

İşleyicinin içinde oluşan istisnalar yakalanır ve yok sayılır; böylece boşaltma her zaman tamamlanır. Başarısız olan bir işleyici bunu sessizce yapar, bu yüzden bir hatanın raporlanması gerekiyorsa gövdeyi kendi try..except bloğuna sarın.

QueueOptions.DrainedMode özelliği, olayın ne zaman tetikleneceğini seçer. qdmTransition (varsayılan) ile olay, aşağıda açıklandığı gibi, dolu durumdan boş duruma her geçişte bir kez tetiklenir. qdmEveryPass ile olay, kuyruklar gönderildikten hemen sonra, kuyruk zaten boş olsa bile ve Text.Level, Binary.Level ve Ping.Level üçü de qmNone olsa bile, bağlantı döngüsünün her geçişinde (yaklaşık her Options.ReadTimeout milisaniyede bir) tetiklenir; bu nedenle sahte bir kuyruk düzeyine gerek yoktur. Bu modda işleyici, bağlantı iş parçacığında bağlantı başına bir kancadır, örneğin bir bağlantıya yapılan her yazmanın kendi iş parçacığından gerçekleşmesi için bekleyen uygulama verilerini WriteData ile göndermek üzere (Binary.Level qmNone iken, olayın içindeki WriteData doğrudan sokete yazar). Geçiş moduna benzer şekilde satır içi çalışır ve NotifyEvents'i izlemez, bu nedenle işleyici hızlı olmalı ve kullanıcı arayüzüne dokunmamalıdır. Yalnızca varsayılan IOHandler (bağlantı başına iş parçacığı) bu döngüye sahiptir; iohIOCP ve iohEPOLL ile olay geçiş başına hiçbir zaman tetiklenmez. Her bağlantı, bağlanırken kuyruk seçeneklerini kopyalar, bu nedenle DrainedMode değerini bileşeni etkinleştirmeden önce ayarlayın, zaten açık olan bağlantılar önceki modu korur.

qdmTransition modunda olay, bağlantı döngüsünün her geçişinde değil, dolu durumdan boş duruma her geçişte bir kez tetiklenir. Bir yoğun gönderimin bittiğine dair bir sinyal değildir. Boşaltma yavaş bir üreticiye ayak uyduruyorsa, her bir ileti kendi olayını tetikleyebilir, çünkü her ileti bir sonraki kuyruğa alınmadan önce yazılıp gönderilir. Olayın bildirdiği tek şey, bu bağlantının kuyruğunun şu anda boş olduğudur, fazlası değil.

Tipik kullanımı akış denetimidir. Sunucu istemciler arasında toplu veri aktarırken, gönderen bir istemciye daha fazla gönderebileceğini bildirmek için bu olayı kullanın. Dur ve bekle alışverişi yerine bir kredi penceresi işletmek için, o bağlantı için hâlâ kaç iletinin kuyrukta olduğunu bildiren TsgcWSConnection sınıfının PendingCount özelliğiyle birlikte kullanın.

Yönetilen .NET sürümü aynı olayı aynı anlamla tetikler. Tek fark, olayın ne sıklıkta geldiğidir. Delphi boşaltması bağlantı döngüsünün her geçişinde bir kez çalışır; bu geçişler Options.ReadTimeOut milisaniye aralıklıdır ve varsayılan değer 10'dur, bu nedenle yavaş bir ileti akışı az sayıda olayda birleştirilir. Yönetilen boşaltma olay tabanlıdır ve aynı akış daha fazla olay tetikleyebilir. Yoğun gönderimler her ikisinde de aynı şekilde davranır.

Örnek


procedure OnQueueDrained(Connection: TsgcWSConnection);
begin
  // runs on the connection thread, do not touch the user interface here
  Connection.WriteData('credit 64');
end;

// qdmEveryPass: runs on every pass of the connection loop
oServer.QueueOptions.DrainedMode := qdmEveryPass;
oServer.QueueOptions.Ping.Level := qmLevel1;

procedure OnQueueDrained(Connection: TsgcWSConnection);
begin
  // runs on the connection thread, do not touch the user interface here
  if Connection.Disconnected then
    exit;
  if HasPendingData then
    Connection.WriteData(GetPendingData);
end;

Olaylara Dön