TsgcHTTP3Client › Events › OnTunnelData
Fires for every DATA frame that arrives on an established Extended CONNECT tunnel.
TsgcHTTP3TunnelDataEvent = procedure(Sender: TObject;
const aData: TBytes) of object;
property OnTunnelData: TsgcHTTP3TunnelDataEvent read FOnTunnelData
write FOnTunnelData;
| Name | Type | Description |
|---|---|---|
Sender | TObject | The TsgcHTTP3Client instance that raised the event. |
aData | const TBytes | The raw tunnelled bytes carried by one DATA frame. This is the payload of the tunnelled protocol, not an HTTP response body. |
Once ExtendedConnect has established a tunnel, the request stream stays open and stops behaving like a request (RFC 9114 Section 4.4). Every DATA frame arriving on it carries tunnelled bytes, so it is delivered here rather than being accumulated into a response body. OnResponse does not fire for tunnel traffic.
The bytes are passed through exactly as received, with one event per DATA frame. Frame boundaries carry no meaning for the tunnelled protocol, so a message may be split across several events or several messages may share one. Reassembly is the caller responsibility: buffer the bytes and parse them according to whatever protocol runs inside the tunnel.
The event only fires while the QUIC event loop is being driven, which means from inside a TunnelPump call, and therefore on the thread that called it. To send in the other direction use TunnelSend.
This member is currently available in the Delphi/C++Builder implementation only.
oClient.OnTunnelData := OnTunnelDataEvent;
if oClient.ExtendedConnect('https://www.example.com/tunnel', 'websocket') then
oClient.TunnelPump(1000);
procedure TfrmMain.OnTunnelDataEvent(Sender: TObject; const aData: TBytes);
begin
Log(Format('tunnel: %d bytes', [Length(aData)]));
end;