sgcWebSockets HTTP Sunucusunda gzip ve deflate Sıkıştırması | eSeGeCe Blog

sgcWebSockets HTTP Sunucusunda gzip ve deflate Sıkıştırması

· Bileşenler

Dünyadaki her tarayıcı, her istekte Accept-Encoding: gzip, deflate gönderir. Şimdiye kadar sgcWebSockets HTTP sunucuları bunu yok sayıyor ve gövdeyi sıkıştırmadan gönderiyordu. HTML dosyalarınız, CSS dosyalarınız, JavaScript kodunuz ve JSON verileriniz, istemci her istekte daha küçüğünü seve seve açacağını size söylüyor olmasına rağmen, tam boyutuyla ağa çıkıyordu.

sgcWebSockets 2026.7, HTTP sunucularına yanıt sıkıştırması ekliyor. İstemci gzip veya deflate desteklediğini bildirdiğinde, sunucu artık yanıtı göndermeden önce sıkıştırabilir. Bu, DocumentRoot üzerinden sunulan statik dosyalar için ve bir olay işleyicide kendiniz oluşturduğunuz yanıtlar için çalışır. Varsayılan olarak kapalıdır, dolayısıyla siz açana kadar sürüm yükseltmesi hiçbir şeyi değiştirmez.

Özelliği açmak

Sıkıştırma, sunucudaki tek bir seçenek nesnesi olan HTTPCompression üzerinden yapılandırılır. TsgcWebSocketHTTPServer bileşeninde bu bir published özelliktir, yani tasarım zamanında Object Inspector üzerinden veya kod içinde ayarlayabilirsiniz:

uses
  sgcWebSocket;

begin
  sgcWebSocketHTTPServer1.HTTPCompression.Enabled := True;
  sgcWebSocketHTTPServer1.Active := True;
end;

Kurulumun tamamı bu kadar. Enabled := True ile sunucu her isteğin Accept-Encoding başlığına bakar ve istemci yapılandırılmış algoritmalardan birini destekliyorsa yanıt gövdesini sıkıştırıp Content-Encoding başlığını buna göre ayarlar. Ayrıca Vary: Accept-Encoding başlığını da ekler; böylece sunucunuzun önündeki önbellekler ve proxy'ler kodlamaya göre anahtarlama yapar ve gzip'lenmiş bir gövdeyi onu okuyamayan bir istemciye vermez.

İstemci sıkıştırma desteği bildirmezse hiçbir şey olmaz ve yanıt tam olarak eskisi gibi gider. Sıkıştırma, istemediği hâlde hiçbir istemciye zorla uygulanmaz.

Algorithms özelliği bir kümedir ve her iki üye de varsayılan olarak etkindir:

sgcWebSocketHTTPServer1.HTTPCompression.Algorithms := [caGZip, caDeflate];

// or gzip only, if you prefer to keep it to a single well-understood encoding
sgcWebSocketHTTPServer1.HTTPCompression.Algorithms := [caGZip];

İstemci her ikisini de desteklediğinde sunucu gzip'i tercih eder.

Ne sıkıştırılır, ne sıkıştırılmaz

Her yanıtı sıkıştırmaya değmez. Hangilerinin sıkıştırılacağına ContentTypes listesi karar verir ve makul bir varsayılanla gelir: text/*, application/json, application/javascript, application/xml, application/xhtml+xml ve image/svg+xml. /* ile biten girdiler bütün bir aileyi eşleştirir, dolayısıyla text/* ifadesi HTML, CSS, düz metin ve geri kalanını kapsar.

Metin, HTML, CSS, JavaScript ve JSON çok iyi sıkışır, çünkü tekrar eden simgeler, etiket adları ve boşluklarla doludur. Hâlihazırda sıkıştırılmış biçimler ise sıkışmaz. Bir JPEG, bir PNG, bir WebP görüntüsü, bir ZIP arşivi, bir .gz dosyası veya bir MP4 videosu fazlalığından zaten arındırılmıştır ve bunu tekrar zlib'den geçirmek, aşağı yukarı aynı boyutta, bazen biraz daha büyük bir gövde üretmek için boşuna CPU harcar. Bu içerik türleri listede yer almaz, dolayısıyla atlanır.

Listeyi kendi listenizle değiştirebilirsiniz:

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;

Denetim, herhangi bir karakter kümesi sonekini yok sayar; dolayısıyla Content-Type: text/html; charset=utf-8 içeren bir yanıt yine de text/* ile eşleşir. Sunucuda ayrıca ek bir güvenlik kuralı vardır: sıkıştırılmış gövde orijinalinden küçük çıkmazsa sıkıştırma atılır ve düz gövde gönderilir. Sıkıştırma olmadan göndereceğinizden daha fazla bayt göndermeniz mümkün değildir.

Sıkıştırma seviyesi ve en küçük boyut

Level, alışılmış zlib seviyesidir, 1 ile 9 arasındadır ve varsayılan olarak 6'dır. Bu varsayılan, hız ile oran arasındaki standart uzlaşmadır ve dünyadaki neredeyse her web sunucusunun çalıştığı değerdir. Onu 9'a çıkarmak her yanıtta ölçülebilir biçimde daha fazla CPU harcar ve JSON için nadiren fazladan bir kazanç sağlar: sıkıştırılmamış gövdeye kıyasla büyük kazanç zaten 1. seviyede gerçekleşir, 6 ile 9 arası seviyeler ise son birkaç yüzde için didişir. Sunucunuz CPU sınırlıysa, 9'a çıkmak yerine 3 veya 4'e inmek çok daha ilginç bir denemedir.

MinSize varsayılan olarak 1024 bayttır ve bundan küçük gövdeler oldukları gibi gönderilir. Bir gzip akışı kendi başlığını ve sonlandırıcısını taşır ve bir kilobaytın altında çerçeveleme yükü ile CPU maliyeti, kazandığınız bir avuç bayta kesinlikle değmez. Küçücük JSON onayları ve kısa yönlendirmeler bu kovaya düşer, düşmeleri de gerekir.

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;

Size ne kazandırır

Kazanç kodunuzda değil, ağ üzerinde ortaya çıkar. Bir HTML sayfası veya bir JSON API yanıtı son derece tekrarlıdır, dolayısıyla birkaç on kilobaytlık tipik bir yük genellikle sunucudan çıkmadan önce birkaç kat sıkışır. Ağda daha az bayt, onları oraya taşımak için daha az gidiş dönüş demektir ve asıl getiri buradadır: mobil bağlantılarda ve yüksek gecikmeli hatlarda, bir yanıtın teslim süresini bant genişliği değil, gidiş dönüş sayısı belirler. Daha az pakete sığan bir gövde basitçe daha erken varır.

Bedeli, sunucuda yanıt başına bir kez harcanan CPU'dur ve varsayılan seviyede küçüktür. Metin ağırlıklı bir site veya bir JSON API için bu takas neredeyse her zaman kabul etmeye değer.

Kendiniz oluşturduğunuz yanıtlar

Olay işleyicilerinizde özel bir şey yapmanız gerekmez. Yanıtı her zamanki gibi oluşturun, ContentText veya ContentStream ile ContentType değerlerini ayarlayın; istemci sıkıştırma istediyse ve içerik türü listedeyse sunucu yanıtı çıkışta sıkıştırır:

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;

Sıkıştırma adımı işleyiciniz döndükten sonra çalışır, dolayısıyla istemcinin gördüğü Content-Length sıkıştırılmış uzunluktur ve Content-Encoding sizin yerinize ayarlanır. Zaten sıkıştırılmış bir gövde sunduğunuz için ContentEncoding değerini kendiniz ayarlarsanız, sunucu yanıtınıza hiç dokunmaz.

İki yanıt türü kasıtlı olarak asla sıkıştırılmaz: arabelleğe alınmaması gereken Server-Sent Events akışları (text/event-stream) ve 204 ile 304 gibi gövdesiz yanıtlar.

DocumentRoot üzerinden sunulan dosyalar

Statik dosyalar hiç kod yazmadan aynı muameleyi görür. Sunucuyu bir klasöre yönlendirin, sıkıştırmayı etkinleştirin; altındaki HTML, CSS, JavaScript, SVG ve JSON dosyaları çıkışta sıkıştırılır. Aynı klasördeki görüntüler ve arşivler sıkıştırılmaz, çünkü içerik türleri listede değildir.

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

HTTP.sys sunucusu

Windows HTTP.sys sunucusu olan TsgcWebSocketServer_HTTPAPI, aynı özelliklere ve aynı varsayılanlara sahip aynı HTTPCompression seçenek nesnesini içerir. Net olarak belirtmeye değer tek bir fark vardır: HTTP.sys sunucusunda bu özellik published değil public'tir, dolayısıyla Object Inspector içinde görünmez. Sunucuyu etkinleştirmeden önce kod içinde ayarlamanız gerekir:

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;

Şimdilik yalnızca HTTP/1.1

Bu sürümde yalnızca HTTP/1.1 yanıtları sıkıştırılır. HTTP/2 ve HTTP/3 yanıtlarına dokunulmaz. Sitenizi HTTP/2 üzerinden sunuyorsanız, bu özellik şimdilik sizin için bir şey değiştirmez. Bir özelliği etkinleştirip hiçbir şeyin neden küçülmediğini merak etmenize izin vermek yerine bunu açıkça belirtmek daha doğru.

Kullanılabilirlik

HTTP yanıt sıkıştırması, sgcWebSockets 2026.7 sürümünde Delphi 7'den 13'e kadar olan sürümlerde ve C++Builder'da, Win32, Win64, Linux64 ve macOS üzerinde kullanılabilir. Varsayılan olarak kapalıdır: HTTPCompression.Enabled := True ayarını yapana kadar mevcut sunucularınızda sürüm yükseltmesiyle hiçbir şey değişmez.

Etkin aboneliği olan müşteriler yeni derlemeyi müşteri alanından indirebilir. Deneme kullanıcıları güncellenmiş yükleyiciyi esegece.com/products/websockets/download adresinden edinebilir.

Sorularınız, geri bildirimleriniz veya kendi sunucunuz için içerik türlerini ayarlama konusunda yardıma mı ihtiyacınız var? Bize ulaşın, yanıtı kodu yazan kişilerden alacaksınız.