sgcQUIC leva o protocolo de transporte QUIC (RFC 9000) para Delphi, C++ Builder e .NET. Ele traz dois novos componentes, TsgcQUICClient e TsgcQUICServer, ambos construídos sobre o mecanismo QUIC nativo do OpenSSL 3.5, de modo que o transporte e o handshake TLS 1.3 são executados como um único fluxo.
O QUIC é o protocolo por baixo do HTTP/3, mas é útil por si só. Ele funciona sobre UDP, multiplexa muitos streams independentes em uma única conexão, retoma com 0-RTT e sobrevive a uma troca de rede graças à migração de conexão. Este post aborda a camada QUIC bruta. O próximo post aborda os componentes HTTP/3 que ficam por cima.
Por que QUIC
Uma conexão clássica de TLS sobre TCP precisa de um handshake TCP e depois de um handshake TLS antes que o primeiro byte de dados da aplicação seja transmitido. O QUIC combina os dois em uma única troca, de modo que uma nova conexão fica pronta em um único round trip, e uma conexão retomada pode enviar dados com 0-RTT.
Como cada stream QUIC é entregue de forma independente, um pacote perdido em um stream não trava os demais. Isso elimina o bloqueio de cabeça de linha (head-of-line blocking) que ocorre quando você multiplexa sobre um único socket TCP. Uma conexão QUIC é identificada por um ID de conexão em vez do par de IP e porta, de modo que ela pode migrar do Wi-Fi para os dados móveis sem cair.
O Cliente QUIC
Defina Host e Port, atribua os eventos e então defina Active como True. O handshake é concluído em um único fluxo, e WriteData envia bytes em um stream QUIC.
uses
sgcQUIC_Client;
var
oClient: TsgcQUICClient;
begin
oClient := TsgcQUICClient.Create(nil);
oClient.Host := 'www.example.com';
oClient.Port := 443;
oClient.OnQUICConnect := OnQUICConnect;
oClient.OnQUICStreamData := OnQUICStreamData;
oClient.OnQUICDisconnect := OnQUICDisconnect;
oClient.Active := True; // TLS 1.3 handshake in a single flight
oClient.WriteData('ping'); // send bytes on a QUIC stream
end;
Os bytes recebidos chegam no evento OnQUICStreamData, que informa o id do stream e o payload:
procedure TForm1.OnQUICStreamData(Sender: TObject; aStreamId: Int64;
aUnidirectional: Boolean; const aData: TBytes);
begin
Memo1.Lines.Add('stream ' + IntToStr(aStreamId) + ': ' +
TEncoding.UTF8.GetString(aData));
end;
O Servidor QUIC
O servidor escuta em uma porta UDP e precisa de um certificado e de uma chave privada no formato PEM. O QUIC sempre roda sobre TLS 1.3, portanto o certificado é obrigatório. Os bytes do cliente chegam em OnQUICData, e você responde com WriteData, passando a conexão que deseja responder.
uses
sgcQUIC_Server;
var
oServer: TsgcQUICServer;
begin
oServer := TsgcQUICServer.Create(nil);
oServer.Port := 443;
oServer.QUICOptions.SSLOptions.CertFile := 'cert.pem';
oServer.QUICOptions.SSLOptions.KeyFile := 'key.pem';
oServer.OnQUICConnect := OnQUICConnect;
oServer.OnQUICData := OnQUICData;
oServer.Active := True;
end;
procedure TForm1.OnQUICData(Sender: TObject;
aConnection: TsgcQUICServerConnection; const aData: TBytes);
begin
// echo the message back to the client that sent it
oServer.WriteData(aConnection, aData);
end;
Streams Multiplexados
Uma única conexão QUIC pode transportar muitos streams ao mesmo tempo. Chame EnableMultiStream antes de se conectar e então abra quantos streams precisar. Um stream bidirecional transporta uma requisição e sua resposta; um stream unidirecional envia dados em um só sentido.
oClient.EnableMultiStream;
oClient.OpenStream; // a new bidirectional stream
oClient.OpenStream(True); // a unidirectional stream
O modo multi-stream usa o mecanismo QUIC embutido do OpenSSL 3.5. Cada stream tem seu próprio controle de fluxo, de modo que um stream lento ou travado nunca bloqueia os demais.
0-RTT e Migração de Conexão
Após um primeiro handshake bem-sucedido, o cliente pode guardar o session ticket e reconectar com 0-RTT, enviando dados da aplicação já no primeiro pacote. A migração de conexão mantém uma sessão viva durante uma troca de rede, o que é importante para clientes móveis que alternam entre Wi-Fi e rede celular. Ambos são tratados pelo mecanismo QUIC subjacente.
Disponibilidade
O sgcQUIC é um pacote separado, licenciado como um add-on do sgcWebSockets Enterprise. Toda licença inclui o código-fonte Pascal completo e um ano de atualizações. Os componentes são instalados na paleta SGC QUIC e oferecem suporte a Delphi e C++ Builder 7 até 13, além de uma versão .NET com os mesmos nomes de classe Tsgc.
Os componentes de cliente e servidor HTTP/3 são abordados em o próximo post. Você pode baixar a versão trial e ler a referência completa dos componentes na página do produto sgcQUIC.
Dúvidas ou feedback? Entre em contato, você receberá uma resposta das pessoas que escreveram o código.
