sgcWebSockets 2026.7: clustering, histórico de mensagens, async / await e clientes reforçados | Blog eSeGeCe

sgcWebSockets 2026.7: clustering, histórico de mensagens, async / await e clientes reforçados

· Lançamentos

O sgcWebSockets 2026.7 é sobre rodar em produção. Agora você pode espalhar uma aplicação WebSocket por vários servidores e manter canais, pub/sub e presença funcionando em todos eles. Os canais podem lembrar suas mensagens recentes, de modo que um cliente que cai e volta recebe tudo o que perdeu. Os clientes reconectam com backoff exponencial e jitter em vez de martelar o servidor todos ao mesmo tempo, a fila de envio pode ser limitada para que um único consumidor lento não esgote a memória do servidor, e o cliente HTTP ganhou um conjunto de proteções contra redirecionamentos que vazam credenciais, TLS rebaixado e respostas sem limite de tamanho.

Além disso, há uma camada async / await para Delphi, gzip e deflate nos servidores HTTP, o novo método HTTP QUERY, verificação de identidade para a criptografia ponta a ponta, OAuth2 no cliente MCP e uma longa lista de correções. Este artigo é o passeio guiado. Cada seção tem um link para o artigo que cobre o recurso em profundidade.

Clustering entre vários servidores

O novo componente TsgcWSCluster une vários servidores sgcWebSockets em um único servidor lógico. Uma mensagem publicada no nó A chega aos inscritos conectados ao nó B, e a presença devolve a lista de todo o cluster em vez de apenas a do nó local. Dois backplanes estão disponíveis: uma malha embutida, na qual os nós conversam diretamente entre si e você não instala nada a mais, e o Redis Pub/Sub para implantações maiores (Enterprise).

uses
  sgcWebSocket, sgcWebSocket_Protocols, sgcWebSocket_Cluster;

oCluster := TsgcWSCluster.Create(nil);
oCluster.EngineType  := clusterMesh;          // no extra infrastructure
oCluster.ClusterPort := 5410;                 // this node's mesh listener
oCluster.Peers.Add('192.168.1.101:5410');     // the other nodes
oCluster.Attach(oProtocol);                   // cluster this protocol's pub/sub
oCluster.Start;

Leia mais: Escalando servidores WebSocket em vários nós.

Histórico de mensagens e recuperação na reconexão

O servidor do protocolo sgc agora pode guardar as últimas N mensagens de cada canal, opcionalmente com um tempo de vida. Quando um cliente reconecta e se inscreve novamente, ele envia o offset da última mensagem que realmente viu, e o servidor reproduz tudo o que foi publicado enquanto ele esteve fora. Nada muda no código do seu cliente além da reinscrição que você já faz, e tudo isso fica desligado a menos que você habilite.

oProtocol.History.Enabled    := True;
oProtocol.History.Size       := 1000;   // last 1000 messages per channel
oProtocol.History.TTLSeconds := 3600;   // optional: also expire after 1 hour

Leia mais: Histórico de mensagens e recuperação na reconexão.

async / await, e um Connect que realmente espera

A nova unit sgcBase_AsyncAwait traz tarefas e futures para a biblioteca. Você pode aguardar uma requisição HTTP, uma conexão WebSocket ou uma resposta de chat de IA sem escrever um único manipulador de evento, encadear o resultado com ThenProc e OnError, e cancelar uma tarefa de uma forma que realmente aborta a requisição subjacente.

No mesmo espírito, Connect agora bloqueia até que a conexão esteja totalmente estabelecida, e não apenas iniciada, e Disconnect espera até que o socket esteja de fato fechado. Isso fecha uma condição de corrida que costumava incomodar durante reconexões rápidas. Quando um connect ou um envio falha, o motivo fica disponível na nova propriedade LastError, e existe uma sobrecarga de Connect que devolve a string de erro diretamente para você, de modo que é possível diagnosticar uma falha sem assinar o OnError.

var
  vError: string;
begin
  if sgcWebSocketClient1.Connect(10000) then
    sgcWebSocketClient1.WriteData('hello')
  else
    ShowMessage('Connect failed: ' + sgcWebSocketClient1.LastError);

  // or get the reason back directly from the call
  if not sgcWebSocketClient1.Connect(vError, 10000) then
    ShowMessage('Connect failed: ' + vError);
end;

Leia mais: async / await em Delphi.

Reforçando o cliente HTTP

Um redirecionamento é a forma mais fácil de perder um token. Se um servidor responde à sua requisição autenticada com um 302 para outro host, o cliente alegremente reenvia os cabeçalhos Authorization e Cookie para lá. O 2026.7 adiciona StripAuthOnCrossHostRedirect para descartá-los em um redirecionamento entre sites e NoInsecureRedirect para recusar um redirecionamento que rebaixe HTTPS para HTTP puro.

As respostas também podem ser limitadas agora, com MaxChunkSize para um único pedaço de uma resposta em chunks e MaxResponseSize para o total. RejectPublicSuffixCookies descarta cookies reivindicados para domínios excessivamente amplos, como "com" ou "co.uk". Para uploads existe o Expect: 100-continue, que pede permissão ao servidor antes de enviar um corpo grande, e um corpo de requisição em chunks para transmitir um upload cujo tamanho você ainda não conhece.

oHTTP.StripAuthOnCrossHostRedirect := True;
oHTTP.NoInsecureRedirect           := True;
oHTTP.MaxResponseSize              := 10 * 1024 * 1024;  // 10 MB, 0 = unlimited
oHTTP.MaxChunkSize                 := 1024 * 1024;       // 1 MB per chunk
oHTTP.RejectPublicSuffixCookies    := True;

Todas essas chaves vêm desligadas por padrão, e nenhuma delas exige que você recorra ao objeto HTTP de baixo nível: elas também estão publicadas nos clientes de API prontos (IA/LLM, exchanges de cripto, OAuth2, Google Cloud, WhatsApp, AWS SQS, WebPush). As proteções de redirecionamento e de tamanho também estão no cliente HTTP/2, e o HTTP/3 ganha o limite de tamanho de resposta. Leia mais: Reforçando o cliente HTTP.

Novas tentativas, backoff e jitter

O WatchDog reconectava em um intervalo fixo, o que significa que mil clientes que perdem o servidor voltam todos no mesmo instante. Agora ele suporta backoff exponencial com um multiplicador, um teto e um jitter aleatório, de modo que a frota se espalha no tempo. O intervalo fixo continua sendo o padrão, então nada muda até você pedir.

O cliente HTTP ganhou uma política de novas tentativas própria: repetir em uma lista configurável de códigos de status, esperar mais a cada vez e respeitar a dica Retry-After do servidor quando ela é enviada. Os clientes OpenAI, Anthropic e Gemini também a usam.

sgcWebSocketClient1.WatchDog.Backoff           := wdbExponential;
sgcWebSocketClient1.WatchDog.BackoffMultiplier := 2.0;   // double every attempt
sgcWebSocketClient1.WatchDog.MaxInterval       := 60;    // seconds, the ceiling
sgcWebSocketClient1.WatchDog.Jitter            := 0.2;   // up to 20% random spread

Leia mais: Backoff exponencial, jitter e Retry-After.

Controle de fluxo na fila de envio

Quando um cliente lê mais devagar do que você escreve, as mensagens enfileiradas se acumulam na memória do servidor. Agora você pode limitar o número de mensagens pendentes por conexão com QueueOptions.MaxQueueSize e escolher o que acontece quando o limite é atingido: descartar a mensagem mais antiga, descartar a mais nova ou desconectar a conexão. O novo evento OnSendBufferFull dispara antes que qualquer coisa seja descartada, então você pode registrá-lo em log, contabilizá-lo ou vetar o descarte para uma conexão que você não pode truncar. A fila é ilimitada por padrão.

oServer.QueueOptions.MaxQueueSize   := 1000;
oServer.QueueOptions.OverflowPolicy := qopDropOldest;  // or qopDropNewest, qopDisconnect

Leia mais: Limites da fila de envio para clientes WebSocket lentos.

gzip e deflate no servidor HTTP

Os servidores HTTP agora podem comprimir suas respostas sempre que o cliente anuncia Accept-Encoding. Isso vale para arquivos servidos a partir de DocumentRoot e para respostas que você mesmo monta em OnCommandGet, ignora corpos abaixo de um tamanho mínimo e tipos de conteúdo que não ficariam menores, e está disponível também no servidor HTTP.sys. A compressão vem desligada por padrão, e por enquanto apenas respostas HTTP/1.1 são comprimidas.

sgcWebSocketHTTPServer1.HTTPCompression.Enabled := True;
sgcWebSocketHTTPServer1.HTTPCompression.Level   := 6;     // 1..9
sgcWebSocketHTTPServer1.HTTPCompression.MinSize := 1024;  // bytes

Leia mais: Compressão gzip e deflate no servidor HTTP.

O método HTTP QUERY

QUERY é um novo método HTTP da IETF que envia uma busca no corpo da requisição como um POST, mas continua seguro e cacheável como um GET, de modo que sua consulta deixa de ser espremida em uma URL com limite de tamanho. O 2026.7 o implementa nos clientes HTTP/1.x, HTTP/2, HTTP/3 e REST, e os servidores e o proxy o tratam.

vResult := oClient.Query('https://api.example.org/contacts', oQuery);

Leia mais: O novo método HTTP QUERY em Delphi.

Verificação de identidade no E2EE

A criptografia ponta a ponta mantém o conteúdo privado, mas por si só não diz quem está do outro lado. Um servidor ou um relay no meio pode entregar a cada lado uma chave própria e ler tudo. No 2026.7 cada lado pode assinar sua chave de criptografia com uma chave de identidade de longo prazo, e o outro lado verifica essa assinatura, de forma que uma troca silenciosa de chaves é detectada em vez de aceita.

Funciona para conversas de um para um e para grupos, adiciona eventos para aprovar ou fixar a identidade de um par e para avisar quando a chave de identidade de um par muda, vem desligado por padrão e é totalmente compatível com pares na versão 2026.6.

E2EE.E2EE_Options.Identity.Enabled    := True;
E2EE.E2EE_Options.Identity.PrivateKey := LoadIdentityPrivateKey;  // PEM
E2EE.E2EE_Options.Identity.PublicKey  := LoadIdentityPublicKey;   // PEM
E2EE.OnE2EEVerifyPeerIdentity := OnE2EEVerifyPeerIdentityEvent;
E2EE.OnE2EEKeyChange          := OnE2EEKeyChangeEvent;

Leia mais: Verificação de identidade no E2EE.

OAuth2 para o cliente MCP e a concessão Identity Assertion

O cliente MCP agora pode autenticar com OAuth2 em vez de uma chave de API estática. Ele obtém o token sozinho, guarda em cache até expirar e o renova, e quando o OAuth2 está habilitado ele tem prioridade sobre a chave de API. Junto com isso, o cliente OAuth2 ganha um novo tipo de concessão, o Identity Assertion Authorization Grant, que encadeia uma identidade de um domínio para outro: o cliente executa toda a troca em várias etapas por você e dispara eventos para que você possa acompanhar cada passo.

MCPClient.MCPOptions.AuthenticationOptions.OAuth2.Enabled := True;
MCPClient.MCPOptions.AuthenticationOptions.OAuth2.GrantType := auth2ClientCredentials;
MCPClient.MCPOptions.AuthenticationOptions.OAuth2.TokenURL := 'https://auth.example.com/oauth2/token';
MCPClient.MCPOptions.AuthenticationOptions.OAuth2.ClientId := 'YOUR_CLIENT_ID';
MCPClient.MCPOptions.AuthenticationOptions.OAuth2.ClientSecret := 'YOUR_CLIENT_SECRET';

Leia mais: OAuth2 para o cliente MCP.

Feeds de cripto: reinscrição e limitação de taxa

Até agora, quando um socket de dados de mercado caía e o WatchDog o trazia de volta, o socket estava no ar mas você não estava inscrito em nada até reproduzir cada inscrição por conta própria. Os clientes das exchanges agora podem fazer isso por você: defina Resubscribe := True e seus streams são restaurados após uma reconexão. Isso cobre Binance, Kraken, Coinbase e cerca de outras quatorze exchanges, além do feed baseado em sessão da XTB. O padrão é False.

Os clientes de API REST ganham um limitador de taxa opcional no lado do cliente, para que uma rajada de requisições não resulte em um banimento temporário por parte de uma exchange. Limite quantas requisições você envia em uma janela de tempo e escolha se uma requisição em excesso espera ou é rejeitada. Desligado por padrão.

oBinance.RateLimit.Enabled     := True;
oBinance.RateLimit.IntervalMs  := 60000;   // one minute window
oBinance.RateLimit.MaxRequests := 1000;
oBinance.RateLimit.Behavior    := rlbWait;

Leia mais: Reinscrição e o limitador de taxa no lado do cliente.

Adições menores

Correções e reforços

O 2026.7 traz uma longa lista de correções. Em vez de repetir todas elas, aqui está o resumo do que elas somam.

Segurança de memória e reforço dos parsers. Leituras além do fim do buffer foram corrigidas no cliente MQTT 5 (um broker que anuncia mais dados do que enviou), no cliente AMQP 1.0 (decodificação de UUID), no parser STUN/TURN (incluindo um laço infinito e endereços IPv6), no canal de dados SCTP do WebRTC e no scanner de frames TCP puro. O cliente e o servidor UDP, incluindo DTLS, não liberam mais um socket duas vezes nem o deixam pendurado na desconexão. Foram acrescentados limites internos onde um par mal comportado poderia fazer a memória crescer sem limite: a fila de mensagens pendentes do MQTT, as inscrições por conexão do protocolo sgc, as chamadas pendentes do servidor WAMP, as linhas de trailer de uma resposta em chunks e a profundidade de aninhamento das tabelas de campos do AMQP.

HTTP/2. Um limite de tamanho após descompressão (64 MB por padrão) fecha um buraco de esgotamento de memória com respostas do tipo "zip bomb", o limite de tamanho da resposta não pode mais ser burlado pela última parte de uma resposta, e uma requisição que falha agora falha imediatamente em vez de esperar todo o timeout.

Criptografia e aleatoriedade. O servidor WebAuthn, o servidor de autorização OAuth2 e os ids de sessão HTTP embutidos agora usam um gerador de números aleatórios criptograficamente seguro, os desafios são de uso único, e os segredos são comparados em tempo constante (client secret, assinatura JWT, senha Basic da API HTTP). Um JWT com assinatura válida mas com uma claim inválida agora é rejeitado em vez de aceito. Com o StrictVerify do OpenSSL habilitado, o certificado também é verificado contra o nome do host, de modo que um certificado válido emitido para outro host é rejeitado. Conexões a um endereço IP e configurações existentes não são afetadas.

Server-Sent Events. Uma resposta em streaming que entregava vários eventos em uma única leitura, ou um evento dividido em duas leituras, perdia todos menos o primeiro. Isso foi corrigido, o que restaura o streaming token a token nos clientes de IA/LLM. O chat em streaming do OpenAI também não estava definindo o flag de stream, então agora ele transmite como os demais provedores.

Clientes de exchanges. Os ids de requisição da Kraken agora são estritamente crescentes, a BitMEX envia sua expiração em segundos em vez de milissegundos, a MEXC assina os parâmetros codificados que realmente envia, a Cryptorobotics não troca mais dois valores nas chamadas por hash, a Deribit renova seu token de login antes que ele expire, e o cliente Forex reporta o erro que antes engolia ao ler o id da conta.

Lazarus e Free Pascal. Três correções de compilação: as interfaces da unit JSON agora usam a convenção de chamada correta em cada plataforma (elas não compilavam no Linux), o cliente Forex não chama mais uma função exclusiva do Delphi para ler o formato numérico, e a unit de troca de chaves pós-quântica não depende mais de size_t.

Há mais no history.txt, incluindo o cliente gRPC (chamadas concorrentes podiam receber as respostas umas das outras, e uma falha de envio era reportada como sucesso), o servidor OpenAPI (o carregamento da spec agora é thread-safe e seus handlers não rodam mais enquanto um lock interno está retido), um vazamento de conexão e de socket no servidor a cada login falho, um crash em respostas do OpenAI sem o campo "message", como as do Ollama e do LM Studio, um WriteAndWaitData corrigido no cliente WinHTTP, e a ocultação de segredos no log do cliente HTTP, de forma que habilitar o log não grava mais tokens em disco em texto claro.

A edição .NET

O sgcWebSockets .NET 2026.7 foca no cliente HTTP. Ele traz o mesmo conjunto de proteções da edição Delphi: remoção de credenciais em um redirecionamento entre sites, bloqueio do rebaixamento de HTTPS para HTTP, limites de tamanho por chunk e no total da resposta, rejeição de cookies de sufixo público, Expect: 100-continue e corpos de requisição em chunks. Elas estão disponíveis nos componentes de cliente HTTP e nos clientes de API prontos (os clientes de IA/LLM, OAuth2, Google Cloud, WhatsApp, AWS SQS, WebPush), e as mesmas proteções de redirecionamento e de tamanho estão no cliente HTTP/2. As correções de tratamento de redirecionamento e de expiração de cookies também estão incluídas. Tudo vem desligado por padrão.

Atualização

O 2026.7 é uma atualização direta para projetos 2026.x existentes. Todo recurso novo desta versão vem desligado por padrão: clustering, histórico de mensagens, backoff, o limite da fila de envio, a compressão HTTP, as proteções do cliente, a verificação de identidade no E2EE e a reinscrição nas exchanges precisam ser habilitados explicitamente, de modo que instalar a nova versão não altera nenhum comportamento até você optar por isso.

Clientes com assinatura ativa podem baixar a nova versão na área de clientes, ou em esegece.com/products/websockets/download.

Dúvidas, comentários ou ajuda na migração? Entre em contato. Você receberá a resposta de quem escreveu o código.