← Torna al blog

WebSocket, gRPC, HTTP/2 tramite proxy: come scegliere il protocollo per il tuo stack

Analizziamo le caratteristiche del proxying di WebSocket, gRPC e HTTP/2: quale protocollo scegliere, come configurare un server proxy e come evitare errori comuni degli sviluppatori.

📅21 settembre 2026

Quando si lavora con i proxy, gli sviluppatori si trovano spesso di fronte al fatto che le impostazioni classiche del proxy HTTP non funzionano per le connessioni WebSocket, e gRPC si interrompe completamente con errori di handshake TLS. Il problema è che WebSocket, HTTP/2 e gRPC non sono semplicemente "varianti di HTTP", ma modelli di trasporto diversi con i propri requisiti per il tunneling, il multiplexing e la gestione degli header. In questo articolo analizzeremo come fare proxy per ciascuno di questi protocolli, quali insidie si incontrano nella pratica e come scegliere il protocollo e il tipo di proxy per un compito specifico — dalla parsing tramite WebSocket ai microservizi gRPC ad alta intensità di carico.

Quali sono le differenze tra i protocolli e perché è importante per il proxy

HTTP/1.1 funziona secondo il modello "richiesta - risposta": il client apre una connessione, invia una richiesta, riceve una risposta e chiude la connessione o la mantiene aperta per la richiesta successiva (keep-alive). I server proxy sono stati ottimizzati per decenni proprio per questo modello — parsing degli header, buffering del corpo della richiesta, semplice instradamento tramite l'header Host.

WebSocket rompe questo modello: dopo l'iniziale handshake HTTP (Upgrade: websocket), la connessione si trasforma in un canale bidirezionale permanente, dove i dati possono fluire in entrambe le direzioni in qualsiasi momento. Il proxy deve "lasciare andare" questa connessione e semplicemente inoltrare i byte in entrambe le direzioni, senza cercare di interpretarli come richieste HTTP.

HTTP/2 aggiunge il multiplexing — più richieste logiche viaggiano attraverso una singola connessione TCP in parallelo, utilizzando frame binari invece di header testuali. Per il proxy, questo significa che non si può semplicemente leggere il testo riga per riga — è necessaria la supporto del protocollo binario HTTP/2 a livello di proxy o un tunneling TCP trasparente sopra TLS.

gRPC va ancora oltre: è costruito rigorosamente su HTTP/2, utilizza Protocol Buffers per la serializzazione e richiede un trasporto compatibile con HTTP/2 lungo tutto il percorso dal client al server. Se il proxy in qualche punto "downgrada" la connessione a HTTP/1.1, la richiesta gRPC semplicemente non passerà.

Comprendere queste differenze è fondamentale, perché la scelta di un tipo di proxy errato o una configurazione scorretta del tunneling porta a interruzioni delle connessioni, timeout e errori difficili da spiegare, che sono complicati da diagnosticare senza comprendere il livello di trasporto.

WebSocket tramite proxy: configurazione e codice

Per WebSocket tramite proxy ci sono due scenari principali: proxy HTTP con il metodo CONNECT (per WSS, cioè WebSocket su TLS) e proxy SOCKS5, che fa tunneling della connessione TCP senza interpretare il protocollo. SOCKS5 di solito presenta meno problemi, poiché è stato progettato inizialmente come "tubo trasparente" per qualsiasi traffico TCP.

Ecco un esempio di connessione a WebSocket tramite un proxy SOCKS5 in Python utilizzando la libreria websockets e python-socks:

import asyncio
from python_socks.sync import Proxy
import websockets
import websockets.sync.client as ws_client

def connect_ws_via_proxy():
    proxy = Proxy.from_url("socks5://user:pass@proxy_host:1080")
    sock = proxy.connect(dest_host="echo.websocket.events", dest_port=443)

    ws = ws_client.connect(
        "wss://echo.websocket.events",
        sock=sock,
        server_hostname="echo.websocket.events"
    )
    ws.send("Hello via proxy")
    print(ws.recv())
    ws.close()

connect_ws_via_proxy()

In Node.js, un compito simile si risolve tramite il pacchetto ws in combinazione con socks-proxy-agent:

const WebSocket = require('ws');
const { SocksProxyAgent } = require('socks-proxy-agent');

const agent = new SocksProxyAgent('socks5://user:pass@proxy_host:1080');
const socket = new WebSocket('wss://echo.websocket.events', { agent });

socket.on('open', () => socket.send('Hello via proxy'));
socket.on('message', (data) => console.log(data.toString()));

Se il proxy è disponibile solo tramite HTTP (con il metodo CONNECT), lo schema è analogo: la maggior parte dei moderni client WebSocket è in grado di funzionare tramite un tunnel HTTP, è importante solo assicurarsi che il proxy non interrompa le connessioni a lungo termine a causa di timeout. Questo è un problema comune con i proxy dei data center economici, che hanno un limite rigido di 30-60 secondi per le connessioni inattive — per le attività di streaming WebSocket, questo è critico, ed è meglio chiarire i parametri keep-alive con il fornitore.

HTTP/2 tramite proxy: multiplexing e insidie

La principale difficoltà con HTTP/2 tramite proxy è che molti server proxy (soprattutto i vecchi Squid o i semplici proxy forward) funzionano solo con HTTP/1.1 e "downgradano" automaticamente la connessione. Per il client, questo è spesso invisibile (la richiesta viene comunque eseguita), ma si perdono i vantaggi del multiplexing — i ritardi aumentano, specialmente con un gran numero di richieste parallele a un singolo host.

Per verificare se la connessione tramite proxy supporta HTTP/2, è possibile utilizzare cURL con il flag --http2 e un output dettagliato:

curl -v --http2 -x http://user:pass@proxy_host:8080 https://example.com

# Nell'output cerca la riga:
# * Using HTTP2, server supports multiplexing
# Se non c'è, la connessione è scesa a HTTP/1.1

In Python, per HTTP/2 tramite proxy è necessaria la libreria httpx con il supporto HTTP/2 attivato:

import httpx

proxies = {
    "http://": "http://user:pass@proxy_host:8080",
    "https://": "http://user:pass@proxy_host:8080",
}

with httpx.Client(proxies=proxies, http2=True) as client:
    response = client.get("https://example.com")
    print(response.http_version)  # ci aspettiamo "HTTP/2"
    print(response.status_code)

Un punto importante: HTTP/2 richiede TLS con estensione ALPN per la negoziazione del protocollo, quindi il proxy deve fare tunneling trasparente del traffico TLS tramite CONNECT, e non terminare TLS autonomamente (a meno che non sia un proxy specializzato compatibile con HTTP/2). È proprio per questo che per le attività con HTTP/2 i proxy residenziali e i proxy dei data center si comportano in modo diverso — è importante chiarire con il fornitore se è supportato il tunneling TLS end-to-end senza interruzione delle negoziazioni ALPN.

gRPC tramite proxy: TLS, ALPN e requisiti speciali

gRPC è il protocollo più esigente in questo insieme. È strettamente legato a HTTP/2 e spesso utilizza TLS bidirezionale (mTLS) per l'autenticazione. Un comune proxy forward, che non supporta il tunneling HTTP/2 CONNECT "così com'è", semplicemente non passerà il traffico gRPC — la connessione si interromperà con errori del tipo UNAVAILABLE: upstream connect error.

Per fare proxy di gRPC in Python (con la libreria grpc) il proxy è impostato tramite variabili d'ambiente, poiché il supporto integrato per i proxy nelle opzioni del channel storicamente non è mai esistito:

import os
import grpc

os.environ["grpc_proxy"] = "http://user:pass@proxy_host:8080"
os.environ["https_proxy"] = "http://user:pass@proxy_host:8080"

channel = grpc.secure_channel(
    "grpc.example.com:443",
    grpc.ssl_channel_credentials()
)

# Esempio di chiamata tramite stub generato
# stub = YourServiceStub(channel)
# response = stub.YourMethod(request)

In Node.js, il proxy per gRPC è configurato tramite le opzioni del channel grpc-js in combinazione con un agente proxy compatibile con HTTP/2:

const grpc = require('@grpc/grpc-js');
const { HttpsProxyAgent } = require('https-proxy-agent');

process.env.grpc_proxy = 'http://user:pass@proxy_host:8080';
process.env.https_proxy = 'http://user:pass@proxy_host:8080';

const client = new YourServiceClient(
  'grpc.example.com:443',
  grpc.credentials.createSsl()
);

Per il funzionamento stabile di gRPC tramite proxy è fondamentale avere una bassa latenza e una connessione TCP stabile senza interruzioni frequenti — i flussi multiplexati di gRPC sono più sensibili ai guasti di rete rispetto alle singole richieste HTTP/1.1. In tali scenari, i proxy residenziali spesso mostrano una stabilità migliore rispetto ai pool di data center economici, poiché il percorso verso il server di destinazione passa attraverso un'infrastruttura di rete più prevedibile.

Tabella comparativa dei protocolli

Protocollo Tipo di connessione Requisiti per il proxy Tipo di proxy raccomandato
HTTP/1.1 richiesta-risposta, keep-alive minimi, qualsiasi proxy HTTP Proxy dei data center
WebSocket canale bidirezionale permanente supporto per connessioni lunghe, senza timeout Proxy residenziali
HTTP/2 flussi binari multiplexati tunneling TLS end-to-end, ALPN Proxy residenziali o dei data center
gRPC HTTP/2 + Protobuf, spesso mTLS bassa latenza, stabilità, HTTP/2 CONNECT Proxy mobili per bypassare filtri severi

Come scegliere il protocollo e il proxy per il proprio stack

La scelta del protocollo è raramente una decisione libera — è dettata dall'API di destinazione. Ma la scelta del tipo di proxy per questo protocollo è già una vostra responsabilità, e qui è opportuno basarsi su uno scenario specifico:

Parsing dei dati tramite WebSocket (ad esempio, streaming di quotazioni o dati in tempo reale da siti di marketplace) richiede una connessione stabile e duratura senza interruzioni a causa di timeout. Qui funzionano meglio i proxy residenziali — raramente vengono colpiti dagli algoritmi antifrode del servizio di destinazione e mantengono la connessione più a lungo rispetto ai tipici pool di data center.

Integrazione con microservizi gRPC tramite un proxy esterno (ad esempio, durante il test di API da diverse geolocalizzazioni) richiede bassa latenza e supporto per HTTP/2 lungo tutto il percorso. A questo scopo, sono adatti gli IP residenziali con una buona instradamento, e per compiti critici in termini di tempo — proxy mobili, se il servizio di destinazione filtra aggressivamente gli intervalli di data center.

Richieste HTTP/2 massicce a API REST/GraphQL con multiplexing — è lo scenario più comune, dove bastano proxy dei data center veloci ed economici, se il servizio di destinazione non blocca gli intervalli di IP dei data center per impostazione predefinita.

Regola generale: più "capriccioso" è il protocollo riguardo alla stabilità della connessione (WebSocket, gRPC), più ha senso utilizzare IP residenziali o mobili. Più semplice e breve è la richiesta (normale HTTP/1.1 o HTTP/2 senza sessioni lunghe), più è comodo lavorare con i proxy dei data center — sono più veloci e offrono una maggiore larghezza di banda.

Errori comuni e le loro soluzioni

Errore 1: WebSocket si interrompe ogni 30-60 secondi. La causa è che il proxy o il bilanciatore intermedio chiude le connessioni "inattive". Soluzione: attivare i frame ping/pong a livello di applicazione con un intervallo inferiore al timeout del proxy (di solito 20-25 secondi sono sufficienti).

Errore 2: gRPC si interrompe con UNAVAILABLE tramite proxy, anche se funziona direttamente. Il proxy non supporta il tunneling HTTP/2 CONNECT. Soluzione: controllare la documentazione del fornitore per la compatibilità con HTTP/2, oppure utilizzare un proxy SOCKS5 che fa tunneling TCP senza interpretare il protocollo.

Errore 3: HTTP/2 viene silenziosamente downgradato a HTTP/1.1. Questo accade spesso a causa della mancanza di supporto ALPN sul proxy. Controlla esplicitamente la versione del protocollo nel codice (come nell'esempio con httpx sopra) — non fidarti del fatto che "funziona", se non hai verificato http_version nella risposta.

Errore 4: Alta latenza durante il multiplexing di gRPC tramite proxy. Spesso causata da un gran numero di nodi intermedi presso il fornitore di proxy. Soluzione: testare la latenza in anticipo tramite una semplice richiesta RTT e scegliere un fornitore con instradamento diretto, specialmente per le chiamate gRPC sensibili al tempo.

Conclusione

WebSocket, HTTP/2 e gRPC richiedono approcci diversi per la configurazione del proxy proprio perché operano su modelli di trasporto diversi: dal semplice "lasciare andare la connessione TCP" per WebSocket al rigoroso supporto di HTTP/2 CONNECT e ALPN per gRPC. Controlla esplicitamente la versione del protocollo nel codice, testa in anticipo la stabilità delle connessioni a lungo termine e scegli SOCKS5 dove è necessaria la massima trasparenza del tunneling.

Se il tuo stack include connessioni WebSocket a lungo termine o chiamate gRPC sensibili alla latenza, ti consigliamo di provare proxy residenziali — offrono connessioni più stabili e prevedibili rispetto ai tipici pool di data center. Per semplici richieste HTTP/2 con alta larghezza di banda, sono adatti proxy dei data center, mentre per compiti con filtraggio antifrode aggressivo del servizio di destinazione — proxy mobili.