Elke browser ter wereld stuurt Accept-Encoding: gzip, deflate mee bij elk verzoek. Tot nu toe negeerden de sgcWebSockets HTTP-servers dat en verstuurden ze de body ongecomprimeerd. Uw HTML, uw CSS, uw JavaScript en uw JSON gingen op volle grootte over de lijn, terwijl de client u bij elk afzonderlijk verzoek vertelde dat hij met plezier een kleinere versie zou uitpakken.
sgcWebSockets 2026.7 voegt compressie van antwoorden toe aan de HTTP-servers. Wanneer de client gzip of deflate aankondigt, kan de server het antwoord nu comprimeren voordat het wordt verzonden. Het werkt voor statische bestanden die vanuit DocumentRoot worden geserveerd en voor antwoorden die u zelf opbouwt in een event handler. Het staat standaard uit, dus een upgrade verandert niets totdat u het inschakelt.
Inschakelen
Compressie wordt geconfigureerd via één enkel options-object, HTTPCompression, op de server. Op TsgcWebSocketHTTPServer is het een published property, dus u kunt het bij het ontwerpen instellen in de Object Inspector, of in code:
uses
sgcWebSocket;
begin
sgcWebSocketHTTPServer1.HTTPCompression.Enabled := True;
sgcWebSocketHTTPServer1.Active := True;
end;
Dat is de volledige configuratie. Met Enabled := True kijkt de server naar de Accept-Encoding-header van elk verzoek, en als de client een van de geconfigureerde algoritmes ondersteunt, comprimeert hij de body van het antwoord en zet hij Content-Encoding overeenkomstig. Hij voegt ook Vary: Accept-Encoding toe, zodat caches en proxies vóór uw server op de encoding indexeren in plaats van een met gzip ingepakte body door te geven aan een client die die niet kan lezen.
Als de client geen compressie aankondigt, gebeurt er niets en gaat het antwoord er precies zo uit als voorheen. Compressie wordt nooit opgedrongen aan een client die er niet om heeft gevraagd.
De property Algorithms is een set, en beide leden staan standaard aan:
sgcWebSocketHTTPServer1.HTTPCompression.Algorithms := [caGZip, caDeflate];
// or gzip only, if you prefer to keep it to a single well-understood encoding
sgcWebSocketHTTPServer1.HTTPCompression.Algorithms := [caGZip];
Wanneer de client beide ondersteunt, geeft de server de voorkeur aan gzip.
Wat wel en niet gecomprimeerd wordt
Niet elk antwoord is het comprimeren waard. De lijst ContentTypes bepaalt welke dat wel zijn, en die wordt geleverd met een verstandige standaardinhoud: text/*, application/json, application/javascript, application/xml, application/xhtml+xml en image/svg+xml. Vermeldingen die eindigen op /* komen overeen met een hele familie, dus text/* dekt HTML, CSS, platte tekst en de rest.
Tekst, HTML, CSS, JavaScript en JSON comprimeren erg goed, omdat ze vol zitten met herhaalde tokens, tagnamen en witruimte. Al gecomprimeerde formaten niet. Een JPEG, een PNG, een WebP-afbeelding, een ZIP-archief, een .gz-bestand of een MP4-video heeft de redundantie er al uitgeperst, en zoiets nogmaals door zlib halen verbrandt alleen CPU om een body van ongeveer dezelfde grootte op te leveren, soms zelfs een iets grotere. Die content types staan niet in de lijst en worden dus overgeslagen.
U kunt de lijst vervangen door uw eigen lijst:
uses
sgcWebSocket, sgcWebSocket_Classes;
begin
with sgcWebSocketHTTPServer1.HTTPCompression do
begin
ContentTypes.Clear;
ContentTypes.Add('text/*'); // html, css, plain text
ContentTypes.Add('application/json'); // your API replies
ContentTypes.Add('application/javascript');
ContentTypes.Add('image/svg+xml');
ContentTypes.Add('application/x-ndjson'); // whatever else you serve
Enabled := True;
end;
sgcWebSocketHTTPServer1.Active := True;
end;
De controle negeert een eventueel charset-achtervoegsel, dus een antwoord met Content-Type: text/html; charset=utf-8 komt nog steeds overeen met text/*. Er zit ook een extra vangnet in de server: als de gecomprimeerde body niet kleiner uitvalt dan het origineel, wordt de compressie weggegooid en gaat de gewone body eruit. U kunt dus nooit meer bytes versturen dan zonder compressie.
Compressieniveau en minimale grootte
Level is het gebruikelijke zlib-niveau, 1 tot 9, en staat standaard op 6. Die standaardwaarde is het klassieke compromis tussen snelheid en compressieverhouding, en het is de waarde waarop vrijwel elke webserver ter wereld draait. Verhogen naar 9 kost meetbaar meer CPU bij elk afzonderlijk antwoord, en voor JSON levert het zelden veel extra op: de grote winst ten opzichte van de ongecomprimeerde body wordt al op niveau 1 behaald, en de niveaus 6 tot 9 vechten om de laatste paar procent. Als uw server CPU-gebonden is, is zakken naar 3 of 4 een veel interessanter experiment dan stijgen naar 9.
MinSize staat standaard op 1024 bytes, en bodies die kleiner zijn worden verzonden zoals ze zijn. Een gzip-stream draagt zijn eigen header en trailer mee, en onder ongeveer een kilobyte zijn die omkadering plus de CPU-kosten simpelweg niet de handvol bytes waard die u bespaart. Kleine JSON-bevestigingen en korte redirects vallen in deze categorie, en dat is terecht.
with sgcWebSocketHTTPServer1.HTTPCompression do
begin
Level := 6; // 1..9, default 6
MinSize := 1024; // bytes, default 1024, smaller bodies are sent as-is
Enabled := True;
end;
Wat het u oplevert
De winst zit op de lijn, niet in uw code. Een HTML-pagina of een JSON-antwoord van een API is zeer repetitief, dus een typische payload van enkele tientallen kilobytes comprimeert meestal meerdere keren voordat hij de server verlaat. Minder bytes op de lijn betekent minder round trips om ze daar te krijgen, en daar zit de echte winst: op mobiele verbindingen en op verbindingen met hoge latency wordt de bezorgtijd van een antwoord bepaald door het aantal round trips, niet door de bandbreedte. Een body die in minder pakketten past, komt gewoon eerder aan.
De kosten zijn CPU op de server, eenmaal per antwoord, en die zijn klein op het standaardniveau. Voor een tekstrijke site of een JSON-API is die ruil bijna altijd de moeite waard.
Antwoorden die u zelf opbouwt
U hoeft niets bijzonders te doen in uw event handlers. Bouw het antwoord op zoals u altijd al deed, stel ContentText of ContentStream en het ContentType in, en de server comprimeert het op de uitgaande weg als de client om compressie vroeg en het content type in de lijst staat:
procedure TForm1.sgcWebSocketHTTPServer1CommandGet(aConnection: TsgcWSConnection;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
if ARequestInfo.Document = '/api/orders' then
begin
AResponseInfo.ContentType := 'application/json';
AResponseInfo.ContentText := GetOrdersAsJSON; // your payload, plain text
// nothing else to do. If the client sent Accept-Encoding: gzip and the
// body is at least MinSize bytes, it goes out gzipped.
end;
end;
De compressiestap draait nadat uw handler is teruggekeerd, dus de Content-Length die de client ziet is de gecomprimeerde lengte, en Content-Encoding wordt voor u ingesteld. Als u ContentEncoding zelf instelt, omdat u een body serveert die al gecomprimeerd is, laat de server uw antwoord volledig met rust.
Twee soorten antwoorden worden bewust nooit gecomprimeerd: Server-Sent Events-streams (text/event-stream), die niet gebufferd mogen worden, en antwoorden zonder body, zoals 204 en 304.
Bestanden die vanuit DocumentRoot worden geserveerd
Statische bestanden krijgen dezelfde behandeling, zonder ook maar één regel code. Wijs de server naar een map, schakel compressie in, en de HTML-, CSS-, JavaScript-, SVG- en JSON-bestanden daaronder worden op de uitgaande weg gecomprimeerd. De afbeeldingen en de archieven in dezelfde map niet, omdat hun content types niet in de lijst staan.
sgcWebSocketHTTPServer1.HTTPUploadFiles.DocumentRoot := 'C:\www';
sgcWebSocketHTTPServer1.HTTPCompression.Enabled := True;
sgcWebSocketHTTPServer1.Active := True;
// GET /index.html -> compressed, text/html is in ContentTypes
// GET /app.js -> compressed
// GET /logo.png -> not compressed, image/png is not in the list
// GET /favicon.ico -> not compressed
De HTTP.sys-server
De Windows HTTP.sys-server, TsgcWebSocketServer_HTTPAPI, heeft hetzelfde HTTPCompression-options-object, met dezelfde properties en dezelfde standaardwaarden. Er is één verschil waarover we precies willen zijn: op de HTTP.sys-server is de property public in plaats van published, dus hij verschijnt niet in de Object Inspector. U moet hem in code instellen, voordat u de server activeert:
uses
sgcWebSocket_Server_HTTPAPI;
begin
sgcWebSocketServer_HTTPAPI1.HTTPCompression.Enabled := True;
sgcWebSocketServer_HTTPAPI1.HTTPCompression.Level := 6;
sgcWebSocketServer_HTTPAPI1.HTTPCompression.MinSize := 1024;
sgcWebSocketServer_HTTPAPI1.Active := True;
end;
Voorlopig alleen HTTP/1.1
In deze release worden alleen HTTP/1.1-antwoorden gecomprimeerd. Antwoorden via HTTP/2 en HTTP/3 worden niet aangeraakt. Als u uw site via HTTP/2 serveert, verandert deze functie voorlopig nog niets voor u. Dat zeggen we liever meteen duidelijk, in plaats van u een property te laten inschakelen en u te laten afvragen waarom er niets kleiner werd.
Beschikbaarheid
Compressie van HTTP-antwoorden is beschikbaar in sgcWebSockets 2026.7 voor Delphi 7 tot en met 13 en C++Builder, op Win32, Win64, Linux64 en macOS. Het staat standaard uit: bij een upgrade verandert er niets aan uw bestaande servers totdat u HTTPCompression.Enabled := True instelt.
Klanten met een actief abonnement kunnen de nieuwe build downloaden in de klantenzone. Trialgebruikers kunnen de bijgewerkte installer ophalen op esegece.com/products/websockets/download.
Vragen, feedback of hulp bij het afstemmen van de content types voor uw eigen server? Neem contact op, u krijgt antwoord van de mensen die de code hebben geschreven.
