4 votes

Le handshake de socket.io échoue sur l'équilibreur de charge Google https

Nous avons la configuration suivante pour l'équilibreur de charge Google HTTPS.

Deux Frontends : 1. Trafic HTTP vers une IP statique 2. Trafic HTTPS vers la même IP statique (DNS configuré sur un nom de domaine)

Règles relatives aux hôtes et aux chemins Tout va vers le backend

Un seul backend : Avec le protocole HTTP et l'affinité de session définie sur l'IP du client.

L'instance dorsale a une application MEAN fonctionnant sur le port 3000.

Depuis notre application côté client, nous pouvons accéder à l'application backend en utilisant le nom de domaine du loadbalancer. Mais nous avons aussi une fonction de chat avec socket.io.

Pour la connexion au socket, nous n'avons pas pu utiliser le nom de domaine du loadbalancer. Il y a une erreur 400.

Si nous essayons d'utiliser l'IP du backend directement pour la connexion au socket, cela fonctionne mais si le client est en HTTPS, cela crée un autre problème car le backend est en http.

La documentation de Google indique que le loadbalancer prend en charge les websockets par défaut. Je ne suis donc pas sûr de ce qui se passe. Tous les autres exemples que je vois sont relativement anciens et non pertinents, je pense. Toute aide est appréciée. Merci.

0 votes

Comme socket.io démarre la connexion par quelques requêtes http, la connexion échouera régulièrement si vous ne disposez pas d'un équilibrage de charge efficace. Vous pouvez donc soit activer l'équilibrage de charge collant dans l'équilibreur de charge (si cette option est prise en charge), soit configurer le client socket.io pour qu'il se connecte directement avec webSocket et n'utilise pas de sondage http au début de la connexion.

1 votes

Comme j'ai essayé de l'expliquer, la documentation de Google indique clairement que l'équilibrage de charge HTTP(S) prend en charge les websockets sans support supplémentaire. Et je ne pense pas qu'il y ait une option de collage disponible sur GCE. Cependant, il existe une affinité de session et je l'ai essayée.

1 votes

Apparemment, vous n'avez pas compris mon commentaire. Une connexion socket.io commence par plusieurs requêtes http avant de passer à une connexion webSocket. Si ces requêtes http ne sont pas collantes et vont au même hôte à chaque fois, alors la connexion socket.io échouera. Vous pouvez forcer le client à se connecter directement avec une webSocket comme transport pour éviter cela ou vous pouvez configurer l'équilibreur de charge pour qu'il soit collant. Vous avez BESOIN de l'une de ces options pour qu'une connexion socket.io fonctionne à travers un équilibreur de charge, même s'il prend en charge les webSockets. socket.io n'est PAS une simple webSocket, il y a des choses par-dessus.

2voto

Md Daud Walizarif Points 191

Pour les WebSockets sur un équilibreur de charge HTTP(S), le délai d'attente du service dorsal (réponse) est une limite de durée de vie de la connexion (les connexions WebSockets sont interrompues après le délai d'attente de réponse configuré). Par conséquent, le délai d'attente doit être défini en fonction de la durée maximale pendant laquelle une connexion WebSocket restera ouverte. La valeur appropriée du délai de réponse dépend de l'application que vous utilisez.

Vous devrez faire quelques expériences pour trouver un délai de réponse approprié afin d'éviter les fermetures de connexion (augmentez légèrement sa valeur et réessayez ; par exemple, si 30 secondes sont insuffisantes, essayez 40sec,50sec, etc.)

Trouvé sur StackOverflow .

1voto

MFC Points 11

Herro, j'ai lutté avec le débogage de ce problème pendant 2 semaines.

Le commentaire de @jfriend00 a fourni la providence pour mon esprit plébéien.

Sur le point de terminaison du déploiement de nodejs, je dois passer l'ordre des transports de la manière suivante :

  app = express()
  server = require('http').Server(app)# {key: tlskey, cert: tlscert},app)
  io = require('socket.io')(server, { transports: ['websocket', 'polling'], cookie:true, secure: true })
  app.use bodyParser.urlencoded(extended: true)

Que se passe-t-il ? Je spécifie à socket.io d'utiliser explicitement le transport websocket. Si cela échoue, veuillez vous rabattre sur le polling. Parce que le GCE Ingress HTTPS définit certains en-têtes (fait des mises à jour d'en-têtes vers wss), j'ai besoin de l'en-tête secure:true afin de les faire correspondre sur mon backend. Sans ce qui précède, un error 400 se produit du côté du client.

Le service fonctionne comme un NodePort avec un Generate_Cookie .

Si cela échoue toujours, essayez simplement transports: ['polling'] il s'agit du protocole le plus élémentaire.

Voici le lien pour le doc socket.io

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X