TsgcWebSocketServerイベント › OnQueueDrained

OnQueueDrained イベント

クライアント接続の送信キューが、メッセージを保持している状態から空になったときに発生します。

構文

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

デフォルト値

解説

対象の接続でメッセージキューイングが有効な場合、つまり QueueOptions.Text.LevelQueueOptions.Binary.LevelQueueOptions.Ping.Level のいずれかに qmNone 以外が設定されている場合にのみ発生します。キューがなければ排出するものがないため、このイベントは発生しません。

このハンドラーは接続スレッド上でインラインに実行され、このコンポーネントの他のすべてのイベントとは異なり、意図的に NotifyEvents を経由してマーシャリングされません。そのため、ユーザーインターフェイスに触れてはいけません。この相違は意図的なものです。このイベントの価値は、接続ループのまさにその時点、つまりキューが空になった直後、次の読み取りの前、ソケットがまだアイドル状態のときに実行されることにあります。これにより、アプリケーションは待つことなく次のクレジットを渡せます。メインスレッドへマーシャリングすると、この利点は失われます。フォーム、グリッド、ラベルの更新は、TThread.QueueTThread.Synchronize、またはメインスレッドへ送るメッセージを使って、アプリケーション自身がマーシャリングする必要があります。

ハンドラー内で発生した例外は捕捉されて破棄されるため、排出処理は常に完了します。ハンドラーが失敗しても通知はされません。失敗を報告する必要がある場合は、本体を独自の try..except ブロックで囲んでください。

このイベントは、接続ループのパスごとではなく、キューが空でない状態から空になる遷移ごとに 1 回発生します。バーストが終了したことを示す信号ではありません。排出が低速なプロデューサーに追いついている場合は、次のメッセージがキューに入る前に各メッセージが書き出されるため、1 通ごとにイベントが発生することもあります。このイベントが示すのは、この接続のキューが現時点で空であるということだけです。

代表的な用途はフロー制御です。サーバーがクライアント間で大量のデータを中継する場合、このイベントを使って送信側クライアントにさらに送信してよいことを伝えます。TsgcWSConnectionPendingCount プロパティ(その接続でまだキューに残っているメッセージ数を返します)と組み合わせると、ストップアンドウェイト方式ではなくクレジットウィンドウ方式を実装できます。

マネージド .NET 版も同じ意味の同じイベントを発生させます。唯一の違いは発生する頻度です。Delphi の排出処理は接続ループのパスごとに実行され、その間隔は Options.ReadTimeOut ミリ秒(デフォルトは 10)です。そのため、ゆっくりとしたメッセージの流れはまとめられ、イベントの数は少なくなります。マネージド版の排出処理はイベント駆動であり、同じ流れでもより多くのイベントが発生することがあります。バーストの場合の動作は両者で同一です。

使用例


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

イベントに戻る