TsgcWebTransportSession › Methoden › AddIncomingStream

AddIncomingStream Methode

Registriert einen vom Peer geöffneten Stream, löst OnStream aus und liefert jede Payload, die damit eingetroffen ist.

Syntax

function AddIncomingStream(aStreamId: Int64; aUnidirectional: Boolean;
  const aData: TBytes): TsgcWebTransportStream;

Parameter

NameTypBeschreibung
aStreamIdInt64Die QUIC-Stream-ID des vom Peer geöffneten Streams. Wird in StreamId des neuen Streams gespeichert, damit der Demultiplexer spätere Daten dorthin leiten kann.
aUnidirectionalBooleanTrue, wenn der Peer einen unidirektionalen Stream geöffnet hat (sein Header war 0x54), False bei einem bidirektionalen (Header 0x41).
aDataconst TBytesAnwendungsbytes, die im selben Lesevorgang wie der Stream-Header eingetroffen sind, wobei der Header bereits entfernt wurde. Sie werden an OnData des neuen Streams geliefert, nachdem OnStream zurückgekehrt ist. Übergeben Sie ein leeres Array, wenn keine nachfolgende Payload vorhanden war.

Rückgabewert

Der neu erstellte und registrierte TsgcWebTransportStream. Die Sitzung besitzt ihn. Die Methode gibt niemals nil zurück.

Hinweise

Dies ist ein Transport-Integrationspunkt, keine Anwendungsmethode. Sie ist das eingehende Gegenstück zu OpenStream: während OpenStream einen Stream erstellt und dessen Header schreibt, übernimmt AddIncomingStream einen Stream, dessen Header bereits gelesen und validiert wurde. Der HTTP/3-Client und -Server rufen sie beim Demultiplexen der QUIC-Verbindung auf. Anwendungscode sollte stattdessen OnStream behandeln, das diese Methode auslöst.

Die Reihenfolge der Operationen ist wichtig und sollte bekannt sein, denn sie bestimmt, was innerhalb Ihres OnStream-Handlers gilt:

  1. Erstellt den Stream mit der angegebenen ID und Richtung und stattet ihn mit dem Fallback-Writer auf Sitzungsebene aus.
  2. Markiert HeaderSent als True, weil der Peer den Header bereits gesendet hat; die Bibliothek darf keinen weiteren schreiben.
  3. Fügt ihn der Liste der Sitzung hinzu, sodass er in StreamCount zählt und sofort für FindStreamById sichtbar ist.
  4. Löst OnStream aus, Ihre Gelegenheit, OnData zuzuweisen.
  5. Wenn aData nicht leer ist, wird es an OnData des Streams übergeben.

Da Schritt 5 auf Schritt 4 folgt, geht eine Payload, die zusammen mit dem Header eintraf, nicht verloren: Weisen Sie OnData innerhalb von OnStream zu, und Sie erhalten sie. Weisen Sie es dort nicht zu, werden diese Bytes still verworfen.

Der Stream wird mit dem sitzungsweiten Fallback-Writer erstellt. Bei einem vom Peer geöffneten bidirektionalen Stream ersetzen ihn der HTTP/3-Client und -Server unmittelbar nach der Rückkehr dieses Aufrufs durch einen streambezogenen Writer, der an den QUIC-Stream des Peers gebunden ist, sodass ein Echo aus OnData auf demselben Stream zurückgeht. Vom Peer geöffnete unidirektionale Streams sind reine Empfangsstreams und behalten den Fallback-Writer; das Schreiben auf einen solchen ist sinnlos.

Die Methode validiert aStreamId nicht gegen die Sitzung und prüft auch nicht auf eine doppelte ID. Von Aufrufern wird erwartet, dass sie den Header varint(0x54|0x41) + varint(SessionId) zuvor geparst und abgeglichen haben.

Dieses Member ist derzeit nur in der Delphi/C++Builder-Implementierung verfügbar. Die .NET-Klasse besitzt ein internal AddIncomingStream(long, bool), das Anwendungscode nicht aufrufen kann und das kein Payload-Argument entgegennimmt: Auf dem verwalteten Stack werden nachfolgende Bytes stattdessen von der Leseschleife des Transports geliefert.

Beispiel


// What a custom QUIC transport does after parsing the WebTransport header
// off a brand-new peer-opened QUIC stream. The shipping HTTP/3 client and
// server do exactly this; applications handle OnStream instead.
var
  oSession: TsgcWebTransportSession;
  oStream: TsgcWebTransportStream;
  vEmpty: TBytes;
begin
  // vSessionId and vPayload came from the 0x54/0x41 + SessionId header
  oSession := FWebTransportSessions.FindBySessionId(vSessionId);
  if not Assigned(oSession) then
    Exit;   // header names a session we do not have

  // Register with an empty payload, so we can bind the writer BEFORE the
  // data is delivered and an echo from OnData can target this stream.
  SetLength(vEmpty, 0);
  oStream := oSession.AddIncomingStream(vStreamId, vUnidirectional, vEmpty);
  if Assigned(oStream) then
  begin
    if (vStreamId >= 0) and not vUnidirectional then
      oStream.OnWriteBytes := DoWebTransportStreamWriteBytes;
    if Length(vPayload) > 0 then
      oStream.ReceiveData(vPayload);
  end;
end;

Zurück zu Methoden