sgcWebSockets 2026.7 trata de funcionar en producción. Ahora puedes repartir una aplicación WebSocket entre varios servidores y mantener los canales, la publicación/suscripción y la presencia funcionando en todos ellos. Los canales pueden recordar sus mensajes recientes, así un cliente que se cae y vuelve recibe todo lo que se perdió. Los clientes se reconectan con backoff exponencial y jitter en lugar de martillear el servidor todos a la vez, la cola de envío puede acotarse para que un consumidor lento no agote la memoria del servidor, y el cliente HTTP ha ganado un conjunto de protecciones frente a redirecciones que filtran credenciales, TLS degradado y respuestas sin límite de tamaño.
Además de eso hay una capa async / await para Delphi, gzip y deflate en los servidores HTTP, el nuevo método HTTP QUERY, verificación de identidad para el cifrado de extremo a extremo, OAuth2 en el cliente MCP y una larga lista de correcciones. Este artículo es la visita guiada. Cada sección enlaza con el artículo que trata la característica en profundidad.
Clustering entre varios servidores
El nuevo componente TsgcWSCluster une varios servidores sgcWebSockets en un único servidor lógico. Un mensaje publicado en el nodo A llega a los suscriptores conectados al nodo B, y la presencia devuelve la lista de todo el clúster en lugar de solo la del nodo local. Hay dos backplanes disponibles: una malla integrada, en la que los nodos hablan entre sí directamente y no instalas nada más, y Redis Pub/Sub para despliegues mayores (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;
Más información: Escalar servidores WebSocket entre varios nodos.
Historial de mensajes y recuperación al reconectar
El servidor del protocolo sgc puede conservar ahora los últimos N mensajes de cada canal, opcionalmente con un tiempo de vida. Cuando un cliente se reconecta y se vuelve a suscribir, envía el offset del último mensaje que vio realmente, y el servidor reproduce todo lo publicado mientras estuvo ausente. Nada cambia en el código de tu cliente más allá de la resuscripción que ya haces, y todo el mecanismo está apagado a menos que lo actives.
oProtocol.History.Enabled := True;
oProtocol.History.Size := 1000; // last 1000 messages per channel
oProtocol.History.TTLSeconds := 3600; // optional: also expire after 1 hour
Más información: Historial de mensajes y recuperación al reconectar.
async / await, y un Connect que espera de verdad
La nueva unidad sgcBase_AsyncAwait trae tareas y futuros a la librería. Puedes esperar una petición HTTP, una conexión WebSocket o una respuesta de chat de IA sin cablear un solo manejador de eventos, encadenar el resultado con ThenProc y OnError, y cancelar una tarea de forma que aborte de verdad la petición subyacente.
En la misma línea, Connect ahora se bloquea hasta que la conexión está totalmente establecida, no simplemente iniciada, y Disconnect espera hasta que el socket está realmente cerrado. Eso cierra una condición de carrera que solía morder durante las reconexiones rápidas. Cuando falla una conexión o un envío, el motivo está disponible en la nueva propiedad LastError, y hay una sobrecarga de Connect que te devuelve directamente la cadena de error, así puedes diagnosticar un fallo sin suscribirte a 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;
Más información: async / await en Delphi.
Reforzar el cliente HTTP
Una redirección es la forma más fácil de perder un token. Si un servidor responde a tu petición autenticada con un 302 hacia otro host, el cliente reenvía tan contento las cabeceras Authorization y Cookie allí. 2026.7 añade StripAuthOnCrossHostRedirect para eliminarlas en una redirección entre sitios y NoInsecureRedirect para rechazar una redirección que degrade HTTPS a HTTP en claro.
Las respuestas también se pueden acotar ahora, con MaxChunkSize para una sola parte de una respuesta troceada y MaxResponseSize para el total. RejectPublicSuffixCookies descarta las cookies reclamadas para dominios demasiado amplios, como "com" o "co.uk". Para las subidas está Expect: 100-continue, que pide permiso al servidor antes de enviar un cuerpo grande, y un cuerpo de petición troceado para transmitir una subida cuyo tamaño todavía no conoces.
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;
Todos estos interruptores están desactivados por defecto, y ninguno te obliga a bajar al objeto HTTP de bajo nivel: también están publicados en los clientes de API ya preparados (IA/LLM, exchanges de criptomonedas, OAuth2, Google Cloud, WhatsApp, AWS SQS, WebPush). Las protecciones de redirección y de tamaño están también en el cliente HTTP/2, y HTTP/3 gana el límite de tamaño de respuesta. Más información: Reforzar el cliente HTTP.
Reintentos, backoff y jitter
El WatchDog se reconectaba con un intervalo fijo, lo que significa que mil clientes que pierden el servidor vuelven todos en el mismo instante. Ahora admite backoff exponencial con un multiplicador, un techo y un jitter aleatorio, así la flota se reparte sola. El intervalo fijo sigue siendo el valor por defecto, así que nada cambia hasta que lo pides.
El cliente HTTP ha ganado su propia política de reintentos: reintentar según una lista configurable de códigos de estado, esperar más cada vez y respetar la indicación Retry-After del servidor cuando la envía. Los clientes de OpenAI, Anthropic y Gemini también la usan.
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
Más información: Backoff exponencial, jitter y Retry-After.
Control de presión en la cola de envío
Cuando un cliente lee más despacio de lo que tú escribes, los mensajes en cola se acumulan en la memoria del servidor. Ahora puedes limitar el número de mensajes pendientes por conexión con QueueOptions.MaxQueueSize y elegir qué pasa cuando se alcanza el límite: descartar el mensaje más antiguo, descartar el más nuevo o desconectar la conexión. El nuevo evento OnSendBufferFull se dispara antes de descartar nada, así puedes registrarlo, contarlo o vetar el descarte para una conexión que no te puedes permitir truncar. La cola es ilimitada por defecto.
oServer.QueueOptions.MaxQueueSize := 1000;
oServer.QueueOptions.OverflowPolicy := qopDropOldest; // or qopDropNewest, qopDisconnect
Más información: Límites de la cola de envío para clientes WebSocket lentos.
gzip y deflate en el servidor HTTP
Los servidores HTTP pueden comprimir ahora sus respuestas siempre que el cliente anuncie Accept-Encoding. Se aplica a los archivos servidos desde DocumentRoot y a las respuestas que construyes tú mismo en OnCommandGet, omite los cuerpos por debajo de un tamaño mínimo y los tipos de contenido que no se harían más pequeños, y está disponible también en el servidor HTTP.sys. La compresión está desactivada por defecto, y por ahora solo se comprimen las respuestas HTTP/1.1.
sgcWebSocketHTTPServer1.HTTPCompression.Enabled := True;
sgcWebSocketHTTPServer1.HTTPCompression.Level := 6; // 1..9
sgcWebSocketHTTPServer1.HTTPCompression.MinSize := 1024; // bytes
Más información: Compresión gzip y deflate en el servidor HTTP.
El método HTTP QUERY
QUERY es un nuevo método HTTP del IETF que envía una búsqueda en el cuerpo de la petición como un POST, pero sigue siendo seguro y cacheable como un GET, así tu consulta ya no tiene que caber a la fuerza en una URL con un límite de longitud. 2026.7 lo implementa en los clientes HTTP/1.x, HTTP/2, HTTP/3 y REST, y los servidores y el proxy lo tratan.
vResult := oClient.Query('https://api.example.org/contacts', oQuery);
Más información: El nuevo método HTTP QUERY en Delphi.
Verificación de identidad E2EE
El cifrado de extremo a extremo mantiene privado el contenido, pero por sí solo no te dice quién está al otro lado. Un servidor o un relay en medio puede darle a cada parte su propia clave y leerlo todo. En 2026.7 cada lado puede firmar su clave de cifrado con una clave de identidad de larga duración, y el otro lado verifica esa firma, así un cambio silencioso de claves se detecta en lugar de aceptarse.
Funciona para conversaciones uno a uno y para chats de grupo, añade eventos para aprobar o fijar la identidad de un par y para avisarte cuando la clave de identidad de un par cambia, está desactivado por defecto y es totalmente compatible con los pares de 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;
Más información: Verificación de identidad E2EE.
OAuth2 para el cliente MCP, y la concesión Identity Assertion
El cliente MCP ya puede autenticarse con OAuth2 en lugar de con una clave de API estática. Obtiene el token él mismo, lo guarda en caché hasta que caduca y lo renueva, y cuando OAuth2 está activado tiene prioridad sobre la clave de API. Junto a eso, el cliente OAuth2 gana un nuevo tipo de concesión, la Identity Assertion Authorization Grant, que encadena una identidad de un dominio a otro: el cliente ejecuta por ti todo el intercambio de varios pasos y lanza eventos para que puedas seguir cada paso.
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';
Más información: OAuth2 para el cliente MCP.
Feeds de criptomonedas: resuscripción y limitación de peticiones
Hasta ahora, cuando se caía un socket de datos de mercado y el WatchDog lo recuperaba, el socket volvía a estar levantado pero no tenías ninguna suscripción hasta que reproducías cada una tú mismo. Los clientes de exchange pueden hacerlo ahora por ti: asigna Resubscribe := True y tus streams se restauran tras una reconexión. Cubre Binance, Kraken, Coinbase y otros catorce exchanges aproximadamente, además del feed basado en sesión de XTB. Está en False por defecto.
Los clientes REST de API ganan un limitador de peticiones opcional en el cliente, así una ráfaga de peticiones no hace que un exchange te bloquee temporalmente. Limita cuántas peticiones envías en una ventana de tiempo y elige si una petición sobrante espera o se rechaza. Desactivado por defecto.
oBinance.RateLimit.Enabled := True;
oBinance.RateLimit.IntervalMs := 60000; // one minute window
oBinance.RateLimit.MaxRequests := 1000;
oBinance.RateLimit.Behavior := rlbWait;
Más información: Resuscripción y el limitador de peticiones en el cliente.
Añadidos menores
- Preajuste TLS. Todos los objetos de opciones TLS publican ahora una propiedad
Preset. AsignarTLSOptions.Preset := tlspSecureDefaultsactiva la verificación del certificado, TLS 1.2 o superior y la comprobación del nombre de host en una sola línea. El valor por defecto,tlspCustom, deja tus ajustes actuales intactos. - Clase de sesión HTTP personalizada. Asigna tu propio descendiente de
TIdHTTPSessiona la propiedadSessionClassdel servidor HTTP antes de arrancarlo y podrás guardar tus propios datos dentro de la sesión, mientras el id de sesión, la cookie, el tiempo de espera y la limpieza siguen funcionando exactamente igual que antes. Si necesitas control total sobre dónde viven las sesiones, también puedes asignar tu propiaSessionList. - Ayudantes de certificados RFC 2253. Nuevas funciones leen el sujeto y el emisor de un certificado como una cadena de nombre distinguido RFC 2253 estándar.
- Cliente WebSocket WinHTTP. Ahora admite inicios de sesión por token/bearer y por URL como el cliente estándar, expone el evento
OnHandshakepara que puedas añadir tus propias cabeceras a la petición de conexión, y puede escribir un archivo de log que registra conexiones, desconexiones y cada mensaje de texto y binario enviado y recibido. Los inicios de sesión con OAuth2, JWT y sesión siguen sin estar disponibles ahí, porque usa la pila de red integrada de Windows y no incluye Indy.
Correcciones y refuerzo
2026.7 trae una larga lista de correcciones. En lugar de repetirlas todas, esto es a lo que se resumen.
Seguridad de memoria y refuerzo de los analizadores. Se corrigieron lecturas más allá del final del búfer en el cliente MQTT 5 (un broker que declara más datos de los que envió), el cliente AMQP 1.0 (decodificación de UUID), el analizador STUN/TURN (incluidos un bucle infinito y las direcciones IPv6), el canal de datos SCTP de WebRTC y el escáner de tramas de TCP en crudo. El cliente y el servidor UDP, incluido DTLS, ya no liberan un socket dos veces ni lo dejan colgando al desconectar. Se añadieron límites internos donde un par malintencionado podría hacer crecer la memoria sin freno: la cola de mensajes pendientes de MQTT, las suscripciones por conexión del protocolo sgc, las llamadas pendientes del servidor WAMP, las líneas de tráiler de una respuesta troceada y la profundidad de anidamiento de las tablas de campos de AMQP.
HTTP/2. Un límite de tamaño descomprimido (64 MB por defecto) cierra un agujero de falta de memoria con respuestas de tipo "zip bomb", el límite de tamaño de respuesta ya no se puede sortear con la última parte de una respuesta, y una petición fallida falla ahora de inmediato en lugar de agotar todo el tiempo de espera.
Criptografía y aleatoriedad. El servidor WebAuthn, el servidor de autorización OAuth2 y los ids de sesión HTTP integrados usan ahora un generador aleatorio criptográficamente seguro, los retos son de un solo uso, y los secretos se comparan en tiempo constante (el secreto de cliente, la firma JWT, la contraseña Basic de la API HTTP). Un JWT con una firma válida pero una reclamación incorrecta se rechaza ahora en lugar de aceptarse. Con StrictVerify activado en OpenSSL, el certificado se comprueba también contra el nombre de host, así un certificado válido emitido para otro host se rechaza. Las conexiones a una dirección IP y los ajustes existentes no se ven afectados.
Server-Sent Events. Una respuesta en streaming que entregaba varios eventos en una sola lectura, o un evento partido entre dos lecturas, perdía todos menos el primero. Esto está corregido, lo que restaura el streaming token a token de los clientes de IA/LLM. El chat en streaming de OpenAI tampoco activaba el flag de stream, así que ahora hace streaming como el resto de proveedores.
Clientes de exchange. Los ids de petición de Kraken son ahora estrictamente crecientes, BitMEX envía su caducidad en segundos en lugar de en milisegundos, MEXC firma los parámetros codificados que envía realmente, Cryptorobotics ya no intercambia dos valores en las llamadas por hash, Deribit renueva su token de inicio de sesión antes de que caduque, y el cliente de Forex informa del error que antes se tragaba al leer el id de cuenta.
Lazarus y Free Pascal. Tres correcciones de compilación: las interfaces de la unidad JSON usan ahora la convención de llamada correcta en cada plataforma (no compilaban en Linux), el cliente de Forex ya no llama a una función exclusiva de Delphi para leer el formato numérico, y la unidad de intercambio de claves post-cuántico ya no depende de size_t.
Hay más en history.txt, incluido el cliente gRPC (las llamadas concurrentes podían recibir las respuestas de otras, y un fallo de envío se informaba como éxito), el servidor OpenAPI (la carga de la especificación es ahora segura entre hilos y tus manejadores ya no se ejecutan mientras se mantiene un bloqueo interno), una fuga de conexión y de socket en el servidor con cada inicio de sesión fallido, un fallo con respuestas de OpenAI sin campo "message", como las de Ollama y LM Studio, un WriteAndWaitData corregido en el cliente WinHTTP, y la ocultación de secretos en el log del cliente HTTP, así activar el registro ya no escribe tokens en disco en texto claro.
La edición .NET
sgcWebSockets .NET 2026.7 se centra en el cliente HTTP. Incorpora el mismo conjunto de protecciones que la edición Delphi: eliminación de credenciales en una redirección entre sitios, bloqueo de una degradación de HTTPS a HTTP, límites de tamaño por trozo y totales de la respuesta, rechazo de cookies de sufijo público, Expect: 100-continue y cuerpos de petición troceados. Están disponibles en los componentes de cliente HTTP y en los clientes de API ya preparados (los clientes de IA/LLM, OAuth2, Google Cloud, WhatsApp, AWS SQS, WebPush), y las mismas protecciones de redirección y de tamaño están en el cliente HTTP/2. También se incluyen las correcciones del tratamiento de redirecciones y de la caducidad de las cookies. Todo está desactivado por defecto.
Actualizar
2026.7 es una actualización directa para los proyectos 2026.x existentes. Todas las novedades de esta versión están desactivadas por defecto: el clustering, el historial de mensajes, el backoff, el límite de la cola de envío, la compresión HTTP, las protecciones del cliente, la verificación de identidad E2EE y la resuscripción en los exchanges tienen que activarse explícitamente, así que instalar la nueva versión no cambia ningún comportamiento hasta que lo pides.
Los clientes con una suscripción activa pueden descargar la nueva versión desde el área de clientes, o desde esegece.com/products/websockets/download.
¿Preguntas, comentarios o ayuda con la migración? Ponte en contacto. Recibirás respuesta de las personas que escribieron el código.
