Thread del server HTTP/2

· Funzionalità

Da sgcWebSockets 2024.2.0 il server HTTP/2 è stato migliorato nella ricezione delle richieste HTTP/2. Ora, per impostazione predefinita, quando il server riceve una nuova richiesta HTTP/2, questa viene messa in coda e gestita da uno dei thread del pool di thread. Questo evita il problema quando diverse richieste vengono inviate sulla stessa connessione e vengono elaborate in sequenza.

Vedi sotto le differenze tra HTTP 1.1 e HTTP 2.0:

HTTP 1.1

 Nel comportamento HTTP tradizionale, quando si effettuano più richieste sulla stessa connessione, il client deve attendere la risposta di ogni richiesta prima di inviare la successiva. Questo approccio sequenziale aumenta in modo significativo il tempo di caricamento delle risorse di un sito web. Per affrontare questo problema, HTTP/1.1 ha introdotto una funzionalità chiamata pipelining, che permette a un client di inviare più richieste senza attendere le risposte del server. Il server, a sua volta, risponde al client nello stesso ordine in cui ha ricevuto le richieste.

Sebbene il pipelining sembrasse una soluzione, ha incontrato alcune difficoltà:


Nel tentativo di ottimizzare il caricamento delle pagine dai server che supportano HTTP/1.1, i browser web hanno implementato un workaround. Aprono sei-otto connessioni parallele al server, permettendo la trasmissione simultanea di più richieste. Questo parallelismo mira a mitigare i problemi associati al pipelining e a migliorare i tempi complessivi di caricamento delle pagine.

La scelta di sei-otto connessioni parallele da parte dei browser web è basata su considerazioni di ottimizzazione. Le ragioni specifiche dietro la scelta di questo numero possono coinvolgere un compromesso tra utilizzo delle risorse, efficienza di rete ed evitare potenziali colli di bottiglia. 

HTTP 2.0

In risposta ai vincoli incontrati nel pipelining, HTTP/2 ha introdotto una funzionalità chiamata multiplexing. Il multiplexing consente una comunicazione più efficiente tra client e server, abilitando la trasmissione concorrente di più richieste e risposte su una singola connessione.

HTTP/2 utilizza un meccanismo di framing binario, il che significa che i messaggi HTTP vengono suddivisi in unità più piccole e indipendenti chiamate frame. Questi frame possono essere interlacciati e inviati sulla connessione indipendentemente l'uno dall'altro. Alla ricezione, i frame vengono riassemblati per ricostruire il messaggio HTTP originale.

Questo meccanismo di framing binario è fondamentale per ottenere il multiplexing in HTTP/2. Consente al browser di inviare più richieste sulla stessa connessione senza incontrare problemi di blocco. Di conseguenza, browser come Chrome utilizzano lo stesso ID di connessione per le richieste HTTP/2, permettendo una comunicazione efficiente e ininterrotta tra client e server.

In sostanza, la funzionalità di multiplexing di HTTP/2, abilitata dal meccanismo di framing binario, migliora l'efficienza e la velocità dello scambio di dati tra client e server facilitando la trasmissione concorrente di più richieste e risposte su una singola connessione.

Componente TsgcWebSocketHTTPServer

Per migliorare le prestazioni del protocollo HTTP/2, le richieste vengono inviate per impostazione predefinita a un pool di thread (per impostazione predefinita 32) ogni volta che il server riceve una nuova richiesta HTTP/2, questo evita attese quando una singola connessione invia molte richieste concorrenti che richiederebbero un'elaborazione sequenziale (nel contesto del thread di connessione) in assenza di questo pool di thread.

Il comportamento del PoolOfThreads può essere configurato nelle seguenti proprietà.


Per affinare le richieste, scegliendo quali devono essere elaborate nel pool di thread (perché sono onerose in termini di tempo) mentre altre possono essere elaborate nel thread di connessione, puoi usare l'evento OnHttp2BeforeAsyncRequest, questo evento viene generato prima di mettere in coda la richiesta nel pool di thread, usa il parametro Async per impostare se la richiesta è eseguita in un thread o no.
procedure OnHTTP2BeforeAsyncRequest(Sender: TObject; Connection: TsgcWSConnection; const ARequestInfo: TIdHTTPRequestInfo; var Async: Boolean);
begin
  if ARequestInfo.Document = '/time-consuming-request' then
    ASync := False;
end;