TsgcQUICServer › TsgcQUICServerConnection

TsgcQUICServerConnection Klasse

Eine einzelne angenommene QUIC-Verbindung. Dies ist das Objekt, das an jedes TsgcQUICServer-Ereignis übergeben wird, und das Handle, mit dem Daten an diesen Peer zurückgesendet werden.

Einführung

Jede vom Listener angenommene QUIC-Verbindung wird durch eine Instanz von TsgcQUICServerConnection repräsentiert. Der Server erstellt sie, besitzt sie und übergibt sie als Parameter aConnection von OnQUICConnect, OnQUICData, OnQUICDisconnect, OnQUICException und OnQUICStreamData. Sie erstellen niemals selbst eine.

Sie verwenden die Verbindung für drei Dinge:

1. Als Ziel von WriteData, das Bytes über den Standard-Stream der Verbindung zurücksendet.

2. Als die Verbindung, auf der OpenStream zusätzliche, vom Server initiierte Streams erstellt.

3. Als Schlüssel für Ihren eigenen sitzungsbezogenen Zustand, weil die Instanz für die Lebensdauer der Verbindung stabil bleibt.

Lebensdauer. Die Instanz gehört der Connections-Liste des Servers, die sie freigibt, wenn der Peer die Verbindung trennt oder wenn Stop aufgerufen wird. Geben Sie sie niemals selbst frei, und behalten Sie niemals eine Referenz darauf, nachdem OnQUICDisconnect für diese Verbindung ausgelöst wurde, weil das Objekt kurz danach zerstört wird.

Eine Verbindung schließen. Es gibt keine Methode Disconnect. Setzen Sie Connected auf False, damit der Server die Verbindung nicht mehr bedient; der Transport gibt sie beim nächsten Durchlauf der Ereignisschleife frei. Um alle Verbindungen auf einmal zu trennen, rufen Sie Stop auf.

Threading. Die Verbindung wird im Hintergrund-Listener-Thread des Servers erstellt, gelesen und freigegeben, und die Ereignisse, die sie erhalten, werden auf demselben Thread ausgelöst. Greifen Sie aus einem Handler nicht direkt auf die VCL/FMX zu und blockieren Sie nicht, denn die gesamte QUIC-Ereignisschleife (jede Verbindung, nicht nur diese) steht still, während ein Handler läuft.

Deklaration

TsgcQUICServerConnection = class
public
  function AddStream(aSSL: PSSL; aStreamId: Int64; aUnidirectional, aIncoming: Boolean): TsgcQUICServerStream;
  function FindStreamById(aStreamId: Int64): TsgcQUICServerStream;
  procedure RemoveStream(const aStream: TsgcQUICServerStream);
  property SSL: PSSL read FSSL write FSSL;
  property Stream: PSSL read FStream write FStream;
  property PeerIP: string read FPeerIP write FPeerIP;
  property PeerPort: Word read FPeerPort write FPeerPort;
  property Connected: Boolean read FConnected write FConnected;
  property ConnectNotified: Boolean read FConnectNotified write FConnectNotified;
  property DefaultStreamAdopted: Boolean read FDefaultStreamAdopted write FDefaultStreamAdopted;
  property CreatedAt: TDateTime read FCreatedAt;
  property Streams: TObjectList read GetStreams;
end;

Properties

NameTypBeschreibung
ConnectedBooleanOb die Verbindung aktiv ist. Der Server pumpt und liest nur Verbindungen, deren Connected True ist. Setzen Sie sie auf False, damit der Server diesen Peer nicht mehr bedient. Der Transport selbst setzt sie auf False, kurz bevor OnQUICDisconnect ausgelöst wird.
CreatedAtTDateTimeSchreibgeschützt. Der Zeitstempel (Now), zu dem das Verbindungsobjekt erstellt wurde, also als die QUIC-Verbindung angenommen wurde. Nützlich für altersbasierte Aufräumarbeiten und Protokollierung.
PeerIPstringDie IP-Adresse des Peers. Lesen Sie die Hinweise unten, bevor Sie sich in Delphi darauf verlassen.
PeerPortWordDer UDP-Port des Peers. Lesen Sie die Hinweise unten, bevor Sie sich in Delphi darauf verlassen.
StreamsTObjectListSchreibgeschützt. Die zusätzlichen (nicht standardmäßigen) QUIC-Streams, die für diese Verbindung verfolgt werden, jeweils ein TsgcQUICServerStream. Die Liste wird beim ersten Zugriff erstellt und besitzt ihre Elemente. Sie wird nur gefüllt, wenn die Verbindung im Multi-Stream-Modus läuft, siehe AlwaysMultiStream.
StreamPSSLDas rohe OpenSSL-Handle des einzigen Standard-Datenstreams der Verbindung, übernommen vom ersten bidirektionalen Stream, den der Peer geöffnet hat. Dies ist der Stream, in den WriteData schreibt. Es ist nil, bis der Peer seinen ersten Stream öffnet. Systemnah, verwenden Sie bevorzugt WriteData.
SSLPSSLDas rohe OpenSSL-Handle der QUIC-Verbindung selbst. Wird für fortgeschrittene Interoperabilität mit der OpenSSL-API bereitgestellt. Geben Sie es nicht frei, es gehört der Verbindung.
ConnectNotifiedBooleanInterne Buchführung. True, sobald OnQUICConnect für diese Verbindung ausgelöst wurde. Die Verbindungsbenachrichtigung wird verzögert, bis der erste Stream des Peers angenommen ist, damit aus dem Handler geschriebene Daten einen Ziel-Stream haben.
DefaultStreamAdoptedBooleanInterne Buchführung. True, sobald der erste bidirektionale Stream des Peers als Stream übernommen wurde. Er wird nur einmal übernommen, spätere Anfrage-Streams werden daher anhand der Stream-ID demultiplext, anstatt den Parser-Zustand der ersten Anfrage wiederzuverwenden.

Methoden

NameBeschreibung
AddStream(aSSL, aStreamId, aUnidirectional, aIncoming)Erstellt einen TsgcQUICServerStream-Wrapper, fügt ihn zu Streams hinzu und gibt ihn zurück. Wird vom Transport aufgerufen, wenn er einen Peer-Stream annimmt, und von OpenStream. Normalerweise rufen Sie stattdessen OpenStream auf.
FindStreamById(aStreamId)Gibt den verfolgten Stream zurück, dessen StreamId übereinstimmt, oder nil. Verwenden Sie sie, um die von OnQUICStreamData gemeldete aStreamId mit einem Stream zu korrelieren, in den Sie schreiben können.
RemoveStream(aStream)Entfernt den Stream aus Streams. Da die Liste ihre Elemente besitzt, gibt dies auch den Wrapper und sein OpenSSL-Stream-Handle frei.

Hinweise

PeerIP und PeerPort werden vom Delphi-Server nicht gefüllt. Beide Eigenschaften sind als lesbar und schreibbar deklariert, aber der Delphi-QUIC-Listener belässt sie bei '' und 0, da die Peer-Adresse für eine über die QUIC-Listener-API angenommene Verbindung nicht aus OpenSSL abrufbar ist. Die mitgelieferte libssl-3.dll (OpenSSL 3.5.5) exportiert nur SSL_set1_initial_peer_addr, einen clientseitigen Setter, mit dem einem Client mitgeteilt wird, wohin er sich verbinden soll. Es gibt keinen passenden Getter SSL_get0_peer_addr, der auf der Serverseite aufgerufen werden könnte, und Verbindungen, die mit SSL_accept_connection angenommen werden, teilen sich den einen UDP-Socket des Listeners, sodass es auch kein BIO pro Verbindung gibt, dessen Peer-Adresse abgefragt werden könnte. Die Einschränkung liegt vorgelagert in OpenSSL und ist nichts, was der Transport auslässt. Folglich findet FindConnectionByPeer in Delphi niemals eine Übereinstimmung.

In der .NET-Implementierung werden beide Eigenschaften gefüllt, und zwar aus dem verwalteten QuicConnection.RemoteEndPoint, das MsQuic bereitstellt. Dies ist also eine der wenigen Stellen, an denen sich die beiden Implementierungen unterscheiden. Identifizieren Sie in Delphi eine Sitzung über die Verbindungsinstanz selbst, die für die Lebensdauer der Verbindung stabil und eindeutig ist, statt über die Peer-Adresse.

Die Liste Streams enthält nur die zusätzlichen Streams. Der Standard-Datenstream ist nicht darin enthalten, er ist das separate Handle Stream. Eine einfache QUIC-Verbindung mit nur einem Stream hat daher eine leere Streams-Liste.

Die .NET-Umsetzung dieser Klasse ist bewusst kleiner: Sie stellt nur PeerIP, PeerPort, Connected und CreatedAt bereit. Die Stream-Sammlung, die rohen OpenSSL-Handles und die internen Buchführungs-Flags haben kein .NET-Gegenstück, da der verwaltete System.Net.Quic-Stack diese Details besitzt.

Beispiel


procedure TfrmServer.OnQUICConnectEvent(Sender: TObject; const aConnection: TsgcQUICServerConnection);
begin
  // the instance identifies the session; PeerIP is not filled in by the Delphi server
  Log(Format('connected at %s (%d live)',
    [DateTimeToStr(aConnection.CreatedAt), oServer.ConnectionCount]));
  // greet the peer over its default stream
  oServer.WriteData(aConnection, TEncoding.UTF8.GetBytes('welcome'));
end;

procedure TfrmServer.OnQUICDataEvent(Sender: TObject; const aConnection: TsgcQUICServerConnection;
  const aData: TBytes);
begin
  // reject an oversized payload by closing this connection only
  if Length(aData) > 1024 * 1024 then
    aConnection.Connected := False
  else
    oServer.WriteData(aConnection, aData);
end;

Anforderungen

VoraussetzungDetail
EditionAll-Access-Edition.
Compiler-DefineQUIC wird deaktiviert ausgeliefert. Entfernen Sie die Auskommentierung von {$DEFINE SGC_PACK_HTTP3} im All-Access-Block von sgcVer.inc, ausgeliefert wird es als {.$DEFINE SGC_PACK_HTTP3}. Das definiert wiederum SGC_QUIC, aber nur, wenn SGC_INDY_LIB definiert ist.
UnitsgcQUIC_Server
OpenSSLOpenSSL 3.5 oder neuer, erforderlich.

Zurück zu TsgcQUICServer