Il WebSocket di Tradovate si chiude esattamente dopo 5 minuti
Il socket trasmette perfettamente per 300 secondi, poi cade senza errori e senza avvisi. Ecco cosa lo chiude davvero, la cadenza di heartbeat che lo prolunga e lo schema di riconnessione che trasforma la caduta in un non-evento.
On This Page
- Cosa significa «il WebSocket si chiude esattamente dopo 5 minuti»
- Principali cause della chiusura del WebSocket a 5 minuti nel 2026
- 1. Frame heartbeat in ritardo o del tutto mancanti
- 2. Limitazione dei timer del browser (setInterval / setTimeout)
- 3. Timeout di inattività o di sessione lato server
- 4. Invio su un socket che non è OPEN (readyState 0)
- 5. Scadenza del token e connessioni di lunga durata
- Come risolvere la chiusura del WebSocket a 5 minuti: passo dopo passo
- Soluzione 1: inviare un frame heartbeat circa ogni 2,5 secondi
- Soluzione 2: sostituire setInterval con un controllo del timestamp o un Web Worker
- Soluzione 3: proteggere ogni invio con un controllo di readyState
- Soluzione 4: aggiungere logica di riconnessione, riautorizzazione e nuova iscrizione
- Tabella di risoluzione dei problemi
- Lo prevenga con PickMyTrade
Quando automatizza strumenti veloci come ES o NQ, poche cose bruciano più di un WebSocket di Tradovate che muore a tempo. Si connette, autorizza, si iscrive ai dati di mercato e tutto scorre benissimo, fino ai 300 secondi, quando il socket cade senza errore, senza motivo di chiusura, senza avviso. È la stessa storia ogni volta: la connessione si chiude esattamente a 5 minuti, anche quando i suoi heartbeat sembrano partire correttamente. Di solito si accompagnano due errori correlati, un'eccezione WebSocket is not open: readyState 0 (CONNECTING) quando il suo codice scrive su un socket semiaperto, e un semplice codice di chiusura 1006 (chiusura anomala) dal peer remoto. Ecco cosa significa davvero la chiusura a 5 minuti nel 2026, le vere cause alla base e lo schema esatto heartbeat più riconnessione che mantiene viva la connessione, oltre a come PickMyTrade gestisce questa infrastruttura per Lei, così che un socket caduto non le costi mai un fill.
Checklist rapida per la chiusura del WebSocket a 5 minuti
- Invii un heartbeat circa ogni 2,5 secondi, un frame il cui testo è un array JSON vuoto,
[]. Lo ometta e Tradovate chiude il socket per inattività. - Non si fidi di setInterval in una scheda del browser, le schede in background vengono limitate, il suo heartbeat supera i 2,5 s e il server riaggancia.
- Invii i suoi heartbeat, una volta che i dati in tempo reale iniziano a scorrere, il server smette di inviarli, quindi il client deve mantenere il ritmo.
- Protegga ogni invio con un controllo di readyState, scriva solo quando il socket è OPEN (1), mai mentre è ancora CONNECTING (0).
- Registri l'evento di chiusura,
ws.addEventListener('close', e => console.log(e))rivela il codice (spesso 1006) e l'eventuale motivo. - Dia per scontato che le cadute avverranno e si riconnetta, incapsuli il socket in modo che una chiusura riautorizzi e si iscriva di nuovo automaticamente.
Cosa significa «il WebSocket si chiude esattamente dopo 5 minuti»
L'API in tempo reale di Tradovate è una connessione WebSocket: la apre, invia un frame di autorizzazione, quindi si iscrive ai dati e agli eventi che le interessano. Per mantenere aperta la connessione, il client è responsabile dell'invio degli heartbeat, piccoli frame keep-alive, con una cadenza fissa. Se smette di inviarli, Tradovate considera il socket inattivo e lo chiude lato server.
Il motivo per cui l'errore cade così spesso sul preciso traguardo dei 5 minuti è che i timeout lungo il percorso di rete, il server, un load balancer o un proxy intermedio, tendono a essere applicati su cifre tonde. La connessione si interrompe esattamente ogni 5 minuti (300 secondi) senza alcun messaggio e, in modo rivelatore, senza heartbeat la caduta avviene invece dopo circa 2 minuti. Quindi gli heartbeat prolungano la vita del socket, ma un heartbeat in ritardo o mancato, o un timer di inattività indipendente da qualche parte sul percorso, può comunque ghigliottinarlo a 300 secondi. Non c'è una causa radice pubblicata per il caso esatto dei 5 minuti, quindi la risposta ingegneristica duratura non è prevenire ogni chiusura, ma sopravviverle.
I due messaggi di errore che vedrà sono sintomi dello stesso problema di fondo. WebSocket is not open: readyState 0 (CONNECTING) significa che il suo codice ha tentato un send() prima che l'handshake fosse completato, cosa comune in una funzione heartbeat che scatta a metà riconnessione. Il codice di chiusura 1006 è il modo in cui browser o libreria dicono “la connessione è caduta in modo anomalo”, senza handshake di chiusura pulito, esattamente ciò che ottiene quando un timer di inattività lato server taglia la linea.
Principali cause della chiusura del WebSocket a 5 minuti nel 2026
1. Frame heartbeat in ritardo o del tutto mancanti
È la causa numero uno. Tradovate si aspetta un frame heartbeat, con contenuto testuale [], circa ogni 2,5 secondi per dimostrare che il client è vivo. Se manca quella finestra, il server avvia il conto alla rovescia per la chiusura. E qui sta il problema: una volta che inizia a trasmettere quotazioni in tempo reale, il server di Tradovate smette di inviare i propri heartbeat, quindi non può contare sul traffico integrato della connessione per mantenerla aperta. Il suo client deve inviare il frame di parentesi vuote secondo un proprio programma.
2. Limitazione dei timer del browser (setInterval / setTimeout)
Se pianifica gli heartbeat con setInterval() o setTimeout() in un browser, è alla mercé della priorità della scheda. Quando la scheda perde il focus, Chrome (e la maggior parte dei browser) abbassa la priorità di quei timer, così un intervallo di “2,5 secondi” può dilatarsi silenziosamente fino a diversi secondi. L'heartbeat supera la scadenza e il socket si chiude, spesso intorno ai 5 minuti, quando si è accumulato abbastanza ritardo.
3. Timeout di inattività o di sessione lato server
Nemmeno un heartbeat perfettamente cadenzato può annullare un timeout applicato a monte. Un proxy, un gateway o la stessa sessione di Tradovate possono limitare il tempo di inattività o la durata totale della connessione, ed è per questo che la chiusura cade su quel sospetto confine tondo di 300 secondi. Poiché ciò è fuori dal suo controllo, la soluzione è la riconnessione, non la prevenzione.
4. Invio su un socket che non è OPEN (readyState 0)
Un WebSocket ha quattro stati: CONNECTING (0), OPEN (1), CLOSING (2) e CLOSED (3). Se il suo ciclo heartbeat o il codice degli ordini chiama send() mentre il socket è ancora a readyState 0, ottiene WebSocket is not open: readyState 0 (CONNECTING) e, spesso, subito dietro un messaggio “Disconnected from Tradovate Market WebSocket”. Colpisce più duramente nell'istante successivo a una caduta, quando la sua riconnessione ha avviato un nuovo socket che non ha ancora completato l'handshake.
5. Scadenza del token e connessioni di lunga durata
Un token di accesso di Tradovate ha una durata limitata e queste connessioni non sono pensate per vivere in eterno; se mantiene un singolo socket aperto per periodi molto lunghi (oltre un giorno), tende a cadere. Se il token scade a metà sessione o la connessione invecchia, il socket si chiude e qualsiasi riautorizzazione con il vecchio token fallisce. La durata dei token varia e cambia nel tempo, quindi verifichi i valori attuali nella documentazione API di Tradovate e rinnovi in modo proattivo invece di aspettare un errore.
Come risolvere la chiusura del WebSocket a 5 minuti: passo dopo passo
Soluzione 1: inviare un frame heartbeat circa ogni 2,5 secondi
L'heartbeat è la base. Con una cadenza di circa 2,5 secondi, invii un frame il cui testo è un array JSON vuoto:
Avvii la routine keep-alive
Dopo che il socket si è aperto e ha autorizzato, avvii una routine keep-alive.
Invii il frame di parentesi vuote
A ogni tick, chiami ws.send('[]'), il frame di parentesi vuote è l'heartbeat di Tradovate.
Mantenga l'intervallo sotto i 2,5 s
Mantenga l'intervallo comodamente sotto il limite (2,5 secondi è l'obiettivo; un po' più spesso è più sicuro che un po' meno).
Non dia mai per scontati i ping del server
Non dia mai per scontato che il server le invierà un ping, dopo che i dati iniziano a scorrere, non lo farà.
Soluzione 2: sostituire setInterval con un controllo del timestamp o un Web Worker
Poiché i timer del browser vengono limitati, non si affidi solo a setInterval, né in una scheda in primo piano né in background. Due alternative collaudate:
- Heartbeat guidati dal timestamp. Registri un timestamp (
new Date()) ogni volta che riceve un messaggio. Lo confronti con l'ultima volta che ha inviato un heartbeat; se sono trascorsi più di 2500 ms, invii[]subito. Questo reagisce al traffico reale invece che a un timer che il browser può mettere a digiuno. - Sposti il timer fuori dal thread principale. Esegua l'heartbeat all'interno di un Web Worker, oppure esegua l'intera connessione come servizio Node.js. Entrambi aggirano del tutto la limitazione delle schede del browser, un processo Node non è affatto soggetto alla penalità delle schede in background.
Soluzione 3: proteggere ogni invio con un controllo di readyState
Elimini l'errore readyState 0 non scrivendo mai su un socket che non è aperto:
Controlli readyState prima di ogni invio
Prima di ogni send(), heartbeat o ordine, controlli if (ws.readyState === WebSocket.OPEN) (cioè lo stato 1).
Salti e lasci subentrare la logica di riconnessione
Se è ancora CONNECTING (0) o già CLOSING/CLOSED, salti l'invio e lasci subentrare la sua logica di riconnessione.
Colleghi listener per tutte le transizioni di stato
Colleghi listener per open, message, error e close in modo che le transizioni di stato siano esplicite, e registri l'oggetto dell'evento close per catturare codice e motivo.
Soluzione 4: aggiungere logica di riconnessione, riautorizzazione e nuova iscrizione
Poiché alcune chiusure a 5 minuti sono imposte a monte e non possono essere prevenute, tratti ogni caduta come un errore recuperabile e ricostruisca automaticamente:
Incapsuli il socket
Incapsuli il socket in una classe o funzione che ne possieda il ciclo di vita, così un unico punto è responsabile della sua creazione e distruzione.
Si riconnetta alla chiusura
Alla chiusura, si riconnetta, apra un socket nuovo invece di cercare di far rivivere quello morto.
Riautorizzi il nuovo socket
Riautorizzi il nuovo socket con un token valido (rigeneri il token prima della scadenza così che ce ne sia sempre uno fresco pronto).
Si iscriva di nuovo a tutto
Si iscriva di nuovo a tutto ciò che aveva, reinvii il suo user/syncrequest e si iscriva di nuovo a ogni feed di dati di mercato, perché un nuovo socket parte senza iscrizioni.
Attenda OPEN prima di inviare
Attenda OPEN prima di inviare qualsiasi cosa sul nuovo socket e aggiunga un breve backoff in modo che una connessione instabile non martelli il server.
Tabella di risoluzione dei problemi
| Errore / segnale | Cosa significa | Soluzione |
|---|---|---|
| Il socket si chiude esattamente a 300 s | Un timeout di inattività o di sessione sul percorso ha tagliato la connessione | Inviare heartbeat ogni ~2,5 s e riconnettersi automaticamente alla chiusura |
| Cade dopo ~2 minuti | Non viene inviato alcun heartbeat | Avviare un keep-alive che invii il frame [] con cadenza di 2,5 s |
| WebSocket is not open: readyState 0 (CONNECTING) | Il codice ha chiamato send() prima che l'handshake fosse completato | Inviare solo quando readyState === OPEN (1); altrimenti saltare |
| Codice di chiusura 1006 | Chiusura anomala senza handshake pulito | Riconnettersi alla chiusura, riautorizzare e iscriversi di nuovo |
| «Disconnected from Tradovate Market WebSocket» | Il socket è caduto a metà flusso | Ricostruire il socket e ripristinare le iscrizioni |
| Heartbeat a posto ma la scheda era inattiva | Il browser ha limitato setInterval/setTimeout | Usare heartbeat basati sul timestamp o un Web Worker / Node.js |
| Caduta dopo un uptime molto lungo | Token scaduto o connessione invecchiata | Rinnovare il token prima della scadenza e riconnettersi secondo una pianificazione |
Lo prevenga con PickMyTrade
PickMyTrade si colloca tra i suoi alert di TradingView e Tradovate e gestisce il livello WebSocket come servizio gestito lato server, così la chiusura a 5 minuti viene trattata prima ancora di raggiungerla:
- Heartbeat gestiti, invia il frame keep-alive con una cadenza affidabile lato server, senza alcuna scheda del browser che limiti il timer.
- Auto-Reconnect & Re-Auth, rileva un socket caduto, ne apre uno nuovo, riautorizza con un token valido e si iscrive di nuovo automaticamente.
- Protezioni sullo stato della connessione, trasmette solo quando il socket è davvero aperto, eliminando gli errori di invio con readyState 0.
- Multi-Account Sync, mantiene sano il flusso di ogni conto collegato così che una singola riconnessione non lasci mai indietro un conto.
Faccia trading senza rifiuti
Inizi la prova gratuita di 7 giorni, colleghi oggi i suoi alert e faccia trading senza rifiuti.
Inizi la prova gratuita di 7 giorniDomande frequenti
Il socket viene chiuso da un timeout di inattività o di sessione sul percorso di connessione, che tende a scattare su cifre tonde come 300 secondi. L'invio di heartbeat prolunga la connessione, ma se un heartbeat ritarda o scatta comunque un timer a monte, il socket cade lo stesso. La soluzione affidabile è heartbeat più riconnessione automatica.
Circa ogni 2,5 secondi. L'heartbeat è un frame il cui testo è un array JSON vuoto, []. Inviarlo leggermente più spesso di ogni 2,5 secondi è più sicuro che rischiare un frame in ritardo.
Solo [], un array JSON vuoto inviato come testo del messaggio WebSocket. Quel frame di parentesi vuote è ciò che Tradovate legge come keep-alive.
Il suo codice ha chiamato send() mentre il socket era ancora in fase di handshake (stato 0), non ancora OPEN (stato 1). Controlli readyState prima di ogni invio e salti la scrittura finché il socket non segnala OPEN, lasciando prima terminare la sua logica di riconnessione.
Non una volta che i dati in tempo reale sono in streaming. Il server smette di inviare heartbeat dopo l'avvio del flusso di dati, quindi il client deve inviare i propri con la cadenza di 2,5 secondi. Non può contare sul traffico del server per mantenere aperta la connessione.
I browser limitano setInterval e setTimeout nelle schede inattive, estendendo il suo heartbeat di 2,5 secondi oltre il limite. Usi heartbeat basati su timestamp agganciati ai messaggi ricevuti, oppure esegua la connessione in un Web Worker o in un processo Node.js per evitare del tutto la limitazione delle schede.
Il codice 1006 è una chiusura anomala senza handshake di chiusura pulito, tipicamente una connessione caduta o un timeout lato server. Non cerchi di prevenire ogni 1006; incapsuli il socket, si riconnetta alla chiusura, riautorizzi con un token nuovo e si iscriva di nuovo ai suoi feed.
Questa guida ha esclusivamente finalità educative e informative e non costituisce consulenza finanziaria, di investimento o di trading. Il trading di futures e di altri prodotti a leva comporta un rischio di perdita sostanziale e non è adatto a tutti gli investitori. PickMyTrade è una piattaforma di automazione indipendente di terze parti e non è affiliata a Tradovate, Inc., né approvata o sponsorizzata da essa. «Tradovate» e tutti i nomi, loghi e marchi correlati sono di proprietà dei rispettivi titolari. Le funzionalità della piattaforma e le procedure cambiano nel tempo, quindi verifichi sempre la procedura attuale nella piattaforma e nella documentazione ufficiali di Tradovate prima di agire.