WebSockets ping / pong, perché non TCP keepalive?

I WebSocket hanno l’opzione di inviare ping all’altra estremità, dove l’altra estremità dovrebbe rispondere con un pong.

Al ricevimento di un frame Ping, un endpoint DEVE inviare un frame Pong in risposta, a meno che non abbia già ricevuto un frame Close. DOVREBBE rispondere con il canvasio Pong non appena ansible.

TCP offre qualcosa di simile sotto forma di keepalive:

[S] Invia al tuo peer un pacchetto di probe keepalive senza dati e il flag ACK triggersto. È ansible farlo a causa delle specifiche TCP / IP, come una sorta di ACK duplicato e l’endpoint remoto non avrà argomenti, poiché TCP è un protocollo orientato al stream. D’altra parte, riceverai una risposta dall’host remoto (che non ha bisogno di supportare keepalive affatto, solo TCP / IP), senza dati e il set ACK.

Penso che TCP Keepalive sia più efficiente, perché può essere gestito all’interno del kernel senza la necessità di trasferire dati nello spazio dell’utente, analizzare un frame websocket, creare un frame di risposta e restituirlo al kernel per la trasmissione. È anche meno traffico di rete.

Inoltre, i WebSocket vengono esplicitamente specificati per essere sempre eseguiti su TCP; non sono agnostici a livello di trasporto, quindi Keepalive TCP è sempre disponibile:

Il protocollo WebSocket è un protocollo indipendente basato su TCP.

Quindi, perché mai vorrebbe utilizzare WebSocket ping / pong invece di keepalive TCP?

I problemi con TCP keepalive sono:

  1. È spento per impostazione predefinita.
  2. Per impostazione predefinita, funziona a intervalli di due ore anziché su richiesta, come previsto dal protocollo Ping / Pong.
  3. Funziona tra proxy piuttosto che end-to-end.

Oltre alla risposta di EJP, penso che potrebbe essere anche correlata ai meccanismi proxy HTTP. Le connessioni Websocket possono anche essere eseguite tramite un server proxy (HTTP). In questi casi il keepalive TCP controllerebbe solo la connessione fino al proxy e non la connessione end-to-end.

http://www.whatwg.org/specs/web-apps/current-work/multipage/network.html#ping-and-pong-frames

.3.4 Cornici Ping e Pong

Le specifiche del protocollo WebSocket definiscono i frame Ping e Pong che possono essere utilizzati per keep-alive, heart-beats, rilevamento dello stato della rete, strumentazione di latenza e così via. Questi non sono attualmente esposti nell’API.

I programmi utente possono inviare ping e frame pong non richiesti come desiderato, ad esempio nel tentativo di mantenere i mapping NAT della rete locale, per rilevare connessioni non riuscite o per visualizzare metriche di latenza per l’utente . I programmi utente non devono utilizzare ping o pong non richiesti per aiutare il server; si presume che i server solleciteranno i pong laddove appropriato per le esigenze del server.

I WebSocket sono stati sviluppati pensando a RTC, quindi quando guardo la funzionalità ping / pong, vedo anche un modo di misurare la latenza. Il fatto che il pong debba restituire lo stesso payload del ping, rende molto conveniente inviare un timestamp e quindi calcolare la latenza dal client al server o viceversa.

Il keepalive TCP non viene passato attraverso un proxy web. Il websocket ping / pong verrà inoltrato tramite proxy web. TCP keepalive è progettato per supervisionare una connessione tra endpoint TCP. Gli endpoint del socket Web non sono uguali agli endpoint TCP. Una connessione web socket può utilizzare diverse connessioni TCP tra due endpoint websocket.