TsgcWebSocketServer › 이벤트 › OnQueueDrained
클라이언트 연결의 송신 큐에 메시지가 있다가 비어 있는 상태로 바뀔 때 발생합니다.
property OnQueueDrained: TsgcWSQueueDrainedEvent;
// TsgcWSQueueDrainedEvent = procedure(Connection: TsgcWSConnection) of object
—
해당 연결에 대해 메시지 큐잉이 활성화되어 있을 때만, 즉 QueueOptions.Text.Level, QueueOptions.Binary.Level 또는 QueueOptions.Ping.Level이 qmNone 이외의 값으로 설정되어 있을 때만 발생합니다. 큐가 없으면 비울 것도 없으므로 이벤트는 발생하지 않습니다.
핸들러는 연결 스레드에서 인라인으로 실행되며, 이 컴포넌트의 다른 모든 이벤트와 달리 의도적으로 NotifyEvents를 통해 마샬링되지 않으므로 사용자 인터페이스를 건드려서는 안 됩니다. 이러한 차이는 의도된 것입니다. 이 이벤트의 가치는 전적으로 연결 루프의 바로 그 지점, 즉 큐가 비워진 직후이자 다음 읽기 전이며 소켓이 아직 유휴 상태일 때 실행된다는 데 있고, 그래서 애플리케이션이 기다리지 않고 다음 크레딧을 내줄 수 있습니다. 이를 메인 스레드로 마샬링하면 그 이점이 사라집니다. 폼, 그리드, 레이블 갱신은 애플리케이션이 TThread.Queue, TThread.Synchronize 또는 메인 스레드로 보내는 메시지를 사용하여 직접 마샬링해야 합니다.
핸들러 내부에서 발생한 예외는 포착되어 무시되므로 큐 비우기는 항상 완료됩니다. 실패한 핸들러는 아무런 알림 없이 조용히 실패하므로, 실패를 보고해야 한다면 본문을 자체 try..except 블록으로 감싸십시오.
이 이벤트는 연결 루프의 각 회차마다가 아니라 큐가 비어 있지 않은 상태에서 비어 있는 상태로 전환될 때마다 한 번 발생합니다. 버스트가 끝났다는 신호가 아닙니다. 큐 비우기가 느린 생산자를 따라잡으면 각 메시지가 다음 메시지가 큐에 들어가기 전에 전송되기 때문에 모든 메시지가 각각 자신의 이벤트를 발생시킬 수 있습니다. 이 이벤트가 알려주는 것은 지금 이 연결의 큐가 비어 있다는 사실뿐이며 그 이상은 아닙니다.
일반적인 용도는 흐름 제어입니다. 서버가 클라이언트 사이에서 대량 데이터를 중계할 때 이 이벤트를 사용하여 보내는 클라이언트에게 더 보내도 된다고 알리십시오. 해당 연결에 아직 큐에 남아 있는 메시지 수를 알려주는 TsgcWSConnection의 PendingCount 속성과 함께 사용하면 정지 후 대기 방식 대신 크레딧 윈도 방식을 구현할 수 있습니다.
관리형 .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;