Déconnexion WebSocket Tradovate : code de fermeture 1006
Votre WebSocket Tradovate meurt avec le code de fermeture 1006, sans le moindre texte explicatif. Voici ce que 1006 signifie réellement, pourquoi il se déclenche, et comment faire en sorte que les reconnexions passent inaperçues.
Votre WebSocket Tradovate alimente un bot sans problème, puis, sans prévenir, il meurt avec le code de fermeture 1006. Aucun texte explicatif, aucun message de fermeture, rien dans les journaux à part une variante de “connexion fermée anormalement.” C'est l'un des échecs les plus frustrants de l'automatisation Tradovate, précisément parce que 1006 ne vous apprend presque rien. La bonne nouvelle : vous n'avez presque jamais besoin de résoudre le mystère. Un 1006 signifie que la connexion est morte sans handshake propre, et la solution fiable consiste à faire en sorte que votre client se reconnecte et se réautorise automatiquement dès que cela se produit : maintenir les heartbeats actifs, détecter la coupure, ouvrir un nouveau socket, se reconnecter, puis se réabonner. Un pont comme PickMyTrade fait exactement cela en coulisses, afin que vos alertes TradingView continuent d'atteindre Tradovate même quand un script brut serait resté muet.
Liste de vérification rapide pour le code de fermeture 1006
- Considérez 1006 comme un symptôme. Cela signifie que le socket s'est coupé sans trame de fermeture, pas qu'un élément précis est cassé.
- Envoyez des heartbeats. Poussez une trame vide
[]environ toutes les 2,5 secondes. Si vous les manquez, le serveur vous déconnecte. - Reconnectez-vous automatiquement à chaque fermeture. Ne faites pas de branchement selon le code. Reconnectez-vous aussi bien sur un
1000propre que sur un1006. - Réautorisez-vous et réabonnez-vous. Un nouveau socket n'est pas authentifié, et les abonnements aux cotations et à la synchronisation utilisateur ne survivent pas à une reconnexion.
- Renouvelez, ne vous reconnectez pas via un nouveau login. Le renouvellement du jeton maintient le socket actif ; une toute nouvelle connexion peut expulser votre session et provoquer la coupure.
- Appliquez un backoff avec jitter. Espacez les tentatives et plafonnez-les pour ne pas déclencher les limites de requêtes de Tradovate.
Ce que signifie réellement le «code de fermeture 1006»
Les codes de fermeture WebSocket sont définis par le protocole lui-même. Une fermeture propre envoie le code 1000 (fermeture normale) accompagné d'une trame de fermeture qui en explique la raison. Le code 1006 est différent : c'est un code réservé que votre bibliothèque WebSocket attribue lorsque la connexion a disparu sans qu'aucune trame de fermeture n'arrive jamais. En d'autres termes, le tuyau TCP sous-jacent au socket s'est rompu, et aucune des deux parties n'a eu la possibilité de se dire au revoir correctement. C'est pourquoi 1006 ne porte jamais de raison lisible par un humain. Il n'y a rien à lire, car le message qui l'aurait porté n'est jamais arrivé à destination.
Il est utile de savoir comment le socket Tradovate communique normalement. Chaque trame envoyée par le serveur est identifiée par un seul caractère de tête : une trame o est le message d'ouverture que vous recevez au moment où le socket se connecte, et votre signal pour vous authentifier ; une trame a transporte un tableau de données JSON (cotations, mises à jour d'ordres, réponses de synchronisation) ; une trame h est un heartbeat ; et une trame c est une fermeture propre. Lorsque Tradovate ferme volontairement la connexion, il envoie c[1000,“...”] avec un message expliquant pourquoi. Un 1006 est l'opposé de ce c bien rangé : aucune trame de fermeture du tout, juste un socket mort et le code de fermeture anormale de la bibliothèque.
Arrêtez donc de chercher un message qui ne viendra jamais, et demandez-vous plutôt ce qui a pu couper la connexion TCP sous un socket de longue durée. C'est dans cette courte liste que se trouve chaque solution réelle.
Principales causes du code de fermeture 1006 en 2026
1. Heartbeats manqués (la règle des 2,5 secondes)
C'est la cause la plus souvent négligée. Une fois votre trame authorize acceptée, le socket Tradovate attend un heartbeat régulier de votre client : un tableau JSON vide, écrit littéralement [], envoyé environ toutes les 2,5 secondes. Ces petites trames prouvent que la connexion est vivante. Si elles s'interrompent, le serveur peut discrètement cesser d'envoyer des données ou couper la connexion, ce qui se traduit de votre côté par un 1006. Si vos déconnexions se regroupent après une pause dans votre code ou une boucle d'événements surchargée, soupçonnez d'abord le heartbeat.
2. Limitation (throttling) des onglets du navigateur
Si votre socket tourne dans un navigateur, il y a un piège sournois. Lorsque l'onglet contenant votre application n'est pas l'onglet actif, Chrome et les autres navigateurs abaissent la priorité de setInterval et setTimeout. Votre heartbeat de 2,5 secondes glisse à plusieurs secondes d'intervalle, le serveur voit une connexion stagnante, et le socket se ferme avec 1006 dès que vous changez d'onglet. La solution consiste à exécuter la boucle de heartbeat dans un web worker (les workers ne sont pas limités de la même manière) ou à exécuter l'ensemble comme un processus Node entièrement en dehors du navigateur.

3. Délais d'inactivité des proxys, NAT ou pare-feux
Tout ce qui se trouve entre votre machine et Tradovate peut couper une connexion qu'il juge silencieuse. Les proxys d'entreprise, les répartiteurs de charge, les tables NAT et les routeurs domestiques coupent couramment les connexions TCP inactives après 30 à 120 secondes, et ils envoient rarement une trame de fermeture en le faisant. C'est le 1006 typique, et un heartbeat correctement cadencé est ce qui maintient la connexion suffisamment active pour y survivre.
4. Expiration du jeton ou une seconde connexion qui vole votre session
Un jeton d'accès Tradovate vit environ 90 minutes, et le laisser expirer pendant que le socket est connecté peut couper la connexion. Pire encore, Tradovate n'autorise que deux sessions simultanées par compte, et la création d'une troisième ferme la plus ancienne. Si un autre script, un test manuel ou un nouveau flux de connexion demande un nouveau jeton pour le même compte, cela peut expulser la session sur laquelle repose votre socket, ce qui se manifeste à nouveau par un 1006. Le schéma sûr consiste à renouveler le jeton sur une minuterie plutôt qu'à se reconnecter, ce qui maintient la session existante, et donc le socket, en vie.
5. Instabilité réseau et tempêtes de reconnexion
De simples coupures réseau provoquent aussi des 1006 : une liaison Wi-Fi instable, un VPS avec un voisin bruyant, un bref incident chez le FAI. Cela reste inévitable. Le piège se trouve dans votre réaction. Si votre logique de reconnexion se déclenche en boucle serrée dès qu'elle voit une fermeture, vous pouvez inonder le point de terminaison de Tradovate de tentatives de connexion, déclencher sa pénalité de requêtes, et transformer un incident de deux secondes en un blocage de plusieurs minutes. Le backoff n'est pas optionnel ici.
Comment corriger le code de fermeture 1006 : étape par étape
Encapsulez le socket et reconnectez-vous à chaque fermeture
Prenez en charge tout le cycle de vie
Placez votre WebSocket dans une classe ou une fonction qui prend en charge tout le cycle de vie : connexion, autorisation, abonnement, heartbeat et démontage.
Attachez un unique gestionnaire de fermeture
Attachez un unique gestionnaire de fermeture qui se déclenche sur toute fermeture, propre ou anormale. Ne faites pas de branchement selon le code. Un 1000 et un 1006 signifient tous deux “le socket a disparu, reconstruisez-le.”
Nettoyez le socket mort et planifiez une reconnexion
À la fermeture, supprimez toutes les références au socket mort, effacez sa minuterie de heartbeat, et planifiez une reconnexion. Ne réutilisez jamais un objet socket fermé.
Sauvegardez votre état avant le démontage
Avant de le démonter, sauvegardez l'état dont vous aurez besoin pour restaurer : les contrats auxquels vous étiez abonné, si une requête de synchronisation utilisateur était ouverte, et votre jeton actuel.
Maintenez le heartbeat actif
Démarrez le heartbeat une fois autorisé
Dès que votre trame authorize est acceptée, commencez à envoyer une trame vide [] toutes les 2,5 secondes.
Déplacez les minuteries du navigateur dans un web worker
Si vous êtes dans un navigateur, déplacez cette minuterie dans un web worker afin qu'un onglet en arrière-plan ne puisse pas la limiter. Sur Node, un simple intervalle suffit.
Surveillez également l'autre côté
Surveillez également l'autre côté. Si vous passez plus de quelques secondes sans aucune trame du serveur, considérez la connexion comme morte et forcez une reconnexion plutôt que d'attendre.

Réautorisez et réabonnez le nouveau socket
Attendez la trame d'ouverture
Attendez la trame d'ouverture o sur le nouveau socket. C'est seulement à ce moment-là qu'il est prêt à s'authentifier.
Renvoyez la trame d'autorisation
Renvoyez la trame authorize avec un jeton d'accès valide, formatée exactement comme le spécifie la documentation actuelle de l'API (le mot-clé request, un id, puis le jeton, avec les séparateurs de ligne vide corrects).
Rejouez chaque abonnement
Une fois l'autorisation réussie, rejouez chaque abonnement à partir de votre état sauvegardé : abonnements aux cotations, requêtes de synchronisation utilisateur, et tout ce que l'ancien socket transportait.
Réconciliez après l'interruption
Réconciliez après l'interruption. Récupérez les positions actuelles et les ordres en cours pour que votre vue corresponde à la réalité, car des événements peuvent s'être déclenchés pendant votre déconnexion.
Renouvelez le jeton sur une minuterie, ne créez pas une nouvelle session
Stockez l'expiration et définissez une minuterie de renouvellement
Lors de votre première connexion, stockez la date d'expiration du jeton et définissez une minuterie pour le renouveler environ 15 minutes avant son échéance.
Renouvelez via le endpoint de renouvellement
Renouvelez via le endpoint de renouvellement, qui prolonge votre session sans nouvelle connexion. Le socket connecté continue de fonctionner sans rien d'autre à faire.
Ne créez jamais une seconde connexion
Ne lancez jamais une toute nouvelle connexion pour un compte qui possède déjà un socket actif. Cela peut vous faire dépasser la limite de deux sessions et couper le socket que vous essayez de protéger.

Appliquez un backoff avec jitter
Commencez avec un à deux secondes
Lors de la première reconnexion, attendez une à deux secondes. À chaque nouvel échec, doublez à peu près le délai.
Ajoutez un petit décalage aléatoire
Ajoutez un petit décalage aléatoire à chaque délai afin que de nombreux clients ne réessaient pas tous au même instant et ne martèlent pas le point de terminaison ensemble.
Plafonnez le maximum
Plafonnez le maximum à 30-60 secondes. Un backoff plafonné et avec jitter récupère rapidement d'un incident sans se transformer en blocage de limite de requêtes auto-infligé.
Tableau de dépannage
| Symptôme | Cause probable | Solution |
|---|---|---|
| 1006 quelques secondes après un changement d'onglet du navigateur | Minuterie de heartbeat limitée dans un onglet en arrière-plan | Exécutez le heartbeat [] dans un web worker ou sur Node |
| 1006 après une pause de code ou une boucle surchargée | Heartbeat interrompu au-delà de ~2,5 secondes | Envoyez [] sur un intervalle fiable de 2,5s, en plus des trames entrantes |
| 1006 après 30 à 120 secondes de silence | Un proxy, un NAT ou un pare-feu a coupé une liaison TCP inactive | Maintenez les heartbeats actifs pour que la liaison ne semble jamais inactive |
| 1006 juste autour de la barre des 90 minutes | Le jeton d'accès a expiré | Renouvelez le jeton ~15 minutes avant son échéance |
| 1006 au moment où vous vous connectez ailleurs | Une nouvelle session vous a fait dépasser la limite de 2 sessions | Renouvelez au lieu de vous reconnecter ; une seule session par compte |
| Tempêtes de 1006, puis un long blocage | Une boucle de reconnexion serrée a déclenché la pénalité de requêtes | Backoff exponentiel avec jitter, plafonné à 30-60s |
Évitez cela avec PickMyTrade
Une couche de reconnexion, un heartbeat résistant au throttling, un système de renouvellement de jeton et une relecture des abonnements représentent beaucoup de plomberie à bien faire soi-même, et un seul cas limite oublié fait tomber vos ordres au pire moment. PickMyTrade se place entre TradingView et Tradovate et gère tout cela pour vous :
- Connexions WebSocket gérées avec reconnexion et réautorisation automatiques, pour qu'un 1006 devienne un simple incident plutôt qu'une panne.
- Heartbeats toujours actifs exécutés côté serveur, bien à l'abri du throttling des onglets du navigateur.
- Renouvellement automatique du jeton et une session unique et propre par compte, pour qu'une expiration à 90 minutes ou une seconde connexion égarée ne vous mette jamais hors ligne.
- Reconnexions respectueuses des limites de requêtes avec un backoff raisonnable, pour que la récupération ne se transforme jamais en blocage par pénalité de requêtes.
Le résultat : vos alertes TradingView atteignent Tradovate de manière fiable, sans que vous ayez à écrire ni à surveiller la moindre ligne de code du cycle de vie WebSocket.
Ne laissez jamais un 1006 vous mettre hors ligne
PickMyTrade gère pour vous la logique de reconnexion, de réautorisation et de heartbeat, afin qu'un WebSocket Tradovate coupé ne vous coûte qu'une seconde, pas une session.
Démarrez votre essai gratuit de 5 joursQuestions fréquentes
Le code 1006 est une fermeture anormale. La connexion TCP sous-jacente s'est coupée sans qu'aucune des deux parties n'envoie de trame de fermeture WebSocket correcte, donc votre bibliothèque signale 1006 sans texte explicatif. C'est un symptôme, pas une cause racine : quelque chose sous la couche WebSocket (un timeout, un reset, un heartbeat manqué, ou une coupure réseau) a tué le tuyau avant qu'une fermeture 1000 propre ne puisse avoir lieu.
Les déclencheurs habituels sont des heartbeats manqués (Tradovate attend une trame de tableau vide environ toutes les 2,5 secondes), un proxy ou un pare-feu inactif qui fait expirer la connexion TCP, le jeton d'accès qui expire ou qui est invalidé par une seconde connexion, ou une simple instabilité réseau sur un VPS ou une connexion domestique. Comme 1006 masque la raison exacte, la solution pratique consiste à se reconnecter et à se réautoriser automatiquement plutôt que de chercher une cause unique.
Environ toutes les 2,5 secondes. Une fois votre trame authorize acceptée, le client doit envoyer une trame de tableau JSON vide, écrite [], à cet intervalle. Si ces heartbeats s'interrompent, le serveur peut cesser d'envoyer des données ou fermer purement et simplement la connexion, ce qui se manifeste souvent de votre côté par un 1006.
Oui. Un tout nouveau socket démarre non authentifié. Une fois ouvert, vous devez à nouveau envoyer la trame authorize avec un jeton d'accès valide, puis renvoyer chaque abonnement (cotations, synchronisation utilisateur, etc.). Les abonnements et l'autorisation ne se reportent pas depuis le socket qui vient de mourir.
Le renouvellement, non. Appeler le endpoint de renouvellement maintient votre session existante valide, et le socket déjà connecté reste actif sans rien d'autre à faire. Ce qui le coupe, c'est de demander un tout nouveau jeton via une nouvelle connexion : Tradovate n'autorise que deux sessions simultanées, donc une nouvelle session peut expulser l'ancienne sur laquelle repose votre socket, et vous voyez alors un 1006.
Chrome et les autres navigateurs limitent setInterval et setTimeout dans les onglets inactifs pour économiser de l'énergie. Cette limitation retarde votre heartbeat de 2,5 secondes, le serveur voit une connexion stagnante, et le socket se ferme avec 1006. Exécuter le heartbeat dans un web worker ou sur un processus Node, plutôt que dans un onglet en arrière-plan, évite cette limitation.
Utilisez un backoff exponentiel avec un peu de jitter aléatoire. Commencez autour d'une à deux secondes, doublez à peu près le délai à chaque tentative échouée, ajoutez un petit décalage aléatoire pour que de nombreux clients ne réessaient pas tous en même temps, et plafonnez le maximum à 30-60 secondes. Se reconnecter en boucle serrée peut déclencher la pénalité de requêtes de Tradovate et prolonger la panne.
Aucune connexion n'est à l'abri d'un 1006, car les réseaux, proxys et serveurs coupent occasionnellement les sockets de longue durée. L'objectif n'est pas de l'éliminer mais d'en faire un non-événement : maintenez les heartbeats actifs, détectez la fermeture instantanément, reconnectez-vous et réautorisez-vous avec un backoff, puis réabonnez-vous. Bien fait, un 1006 ne vous coûte qu'une seconde ou deux au lieu de mettre votre bot hors ligne.
Ce guide est fourni à des fins éducatives et informatives uniquement et ne constitue pas un conseil financier, d'investissement ou de trading. Le trading de contrats à terme et d'autres produits à effet de levier comporte un risque de perte substantiel et ne convient pas à tous les investisseurs. PickMyTrade est une plateforme d'automatisation tierce indépendante et n'est affiliée à, approuvée par, ni sponsorisée par Tradovate, Inc. ou Bookmap. Tous les noms, logos et marques associés sont la propriété de leurs détenteurs respectifs. Les fonctionnalités et les étapes de la plateforme évoluent avec le temps ; vérifiez donc toujours le processus actuel dans la documentation officielle de la plateforme avant d'agir.