TsgcWebTransportSession › Methoden › OpenStream
Öffnet einen neuen ausgehenden WebTransport-Stream, bidirektional oder unidirektional, sendet dessen Stream-Header und gibt das Stream-Objekt zurück.
function OpenStream(aUnidirectional: Boolean): TsgcWebTransportStream;
| Name | Typ | Beschreibung |
|---|---|---|
aUnidirectional | Boolean | True öffnet einen unidirektionalen Stream: Sie können schreiben, der Peer kann nur lesen. False öffnet einen bidirektionalen Stream: Beide Seiten können schreiben, der Peer kann also auf demselben Stream antworten. |
Ein neuer TsgcWebTransportStream, bereits bei der Sitzung registriert und schreibbereit. Die Sitzung besitzt ihn, geben Sie ihn nicht frei. Die Methode gibt nie nil zurück.
OpenStream führt vier Schritte in dieser Reihenfolge aus:
StreamId ausfüllt und einen Writer pro Stream bindet. Sowohl der HTTP/3-Client als auch der Server weisen diesen Hook zu.varint(0x54) + varint(SessionId) für einen unidirektionalen Stream, varint(0x41) + varint(SessionId) für einen bidirektionalen, und setzt HeaderSent auf True.
Der Header wird einmal gesendet, und zwar von OpenStream selbst. Alles, was Sie anschließend an WriteData übergeben, ist reine Anwendungs-Payload.
Weisen Sie OnData zu, bevor Sie schreiben. Auf einem bidirektionalen Stream kann der Peer sofort antworten, hängen Sie daher OnData am zurückgegebenen Stream ein, bevor Sie das erste WriteData ausführen. Stellen Sie auf dem Client außerdem sicher, dass WebTransportProcessEvents gepumpt wird, sonst wird die Antwort nie gelesen.
Wenn kein Transport OnOpenStream zugewiesen hat, behält der Stream seinen Fallback-Writer, StreamId bleibt -1, und alle Bytes werden über den OnWriteData-Writer auf Sitzungsebene geleitet. Das bildet einen einzelnen gemultiplexten Transport-Stream ab und entspricht nicht dem, was der ausgelieferte HTTP/3-Client und -Server tun.
.NET-Unterschied. Auf dem verwalteten Stack vergibt die Sitzung die Stream-ID selbst, als fortlaufenden Zähler beginnend bei SessionId, und der Transport-Hook überschreibt sie nicht. Die StreamId eines lokal geöffneten Streams ist unter .NET daher ein synthetisches Handle und nicht die echte QUIC-Stream-ID, die sie in Delphi und C++Builder ist. Vom Peer geöffnete Streams tragen auf beiden Stacks die echte QUIC-Stream-ID. Die Bytes auf der Leitung sind in beiden Fällen identisch; nur der Wert, den Sie zurücklesen können, unterscheidet sich.
var
oStream: TsgcWebTransportStream;
begin
// False = bidirectional, so the server can answer on the same stream
oStream := oSession.OpenStream(False);
oStream.OnData := OnStreamDataEvent; // assign BEFORE writing
oStream.OnClose := OnStreamCloseEvent;
oStream.WriteData('Request payload');
memoLog.Lines.Add('bidi stream opened: id=' + IntToStr(oStream.StreamId));
// A fire-and-forget notification channel: True = unidirectional
with oSession.OpenStream(True) do
WriteData('telemetry: started');
end;