J'utilise socket.io
Dans mon application node.js
Qui s'exécute sur express
.
Tout va bien sur la version locale (localhost
) cependant quand je bascule sur mon serveur de production (qui est servi via https
en utilisant un certificat personnalisé), j'obtiens l'erreur suivante dans ma console de navigateur:
websocket.js:112 WebSocket connection to 'wss://infranodus.com/socket.io/?EIO=3&transport=websocket&sid=j_WBxkPY_RlpF9_ZAANP' failed: Error during WebSocket handshake: Unexpected response code: 400
J'ai fait une recherche ( problème référencé ici ) et il s'avère que cela se produit car mon application/fournisseur d'hébergement bloque les connexions comme wss
et mon socket.io
Retombe sur AJAX
pour faire des requêtes (qui fonctionne bien, mais il y a parfois des bugs).
Je voulais donc vous demander si je pouvais apporter des modifications à mon application pour me débarrasser de cette erreur?
Pour info, toutes les demandes à http://infranodus.com sont actuellement transmises (via .htaccess statique) à https://infranodus.com et mon app.js
(la partie de l'activation du serveur ressemble à ça):
var http = require('http');
var app = express();
var server = http.Server(app);
var io = require('socket.io')(server);
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
et la façon dont j'ai besoin de sockets dans mon fichier frontal:
<script src="/socket.io/socket.io.js"></script>
et alors
var socket = io();
Peut-être que le problème est que j'active le serveur dans mon application node.js en utilisant http
et non https
? Mais je ne voudrais pas passer à cela parce que je ne sais pas où mes certificats sont stockés et je ne voudrais pas trop changer le code backend.
MISE À JOUR (21/10/2018): Nous avons compris que le problème était avec le serveur nginx et en raison des limitations de certains les fournisseurs d'hébergement qui n'autorisent pas les utilisateurs à modifier les serveurs nginx, les websockets via un protocole sécurisé sont bloqués ou obtiennent une erreur 400. Ce serait bien de résoudre cela dans sockets.io car c'est un problème que beaucoup d'utilisateurs ont. Des idées?
POUR REPRODUIRE LE PROBLÈME: Veuillez ouvrir votre console Javascript et aller sur https://infranodus.com/news/english =
CODE SOURCE: https://github.com/noduslabs/infranodus
Vérifiez si vous utilisez express-status-monitor
en tant que middleware sur express, cela fait que l'appel http sur la première (demande) prise de contact de WebSocket échoue, sinon peut-être un autre facteur comme proxy (nginx) ou similaire comme ça
Regardez ici Plus de détails sur cette erreur
J'ai eu la même erreur.
J'ai décidé de visiter infranodus.com/socket.io/?EIO=3&transport=websocket&sid=j_WBxkPY_RlpF9_ZAANP qui renvoie le message "ID de session inconnu".
Avez-vous utilisé plusieurs nœuds? Si tel est le cas, veuillez vous référer au site https://socket.io/docs/using-multiple-nodes/ .
Comme il est dit sur le site officiel,
Si vous prévoyez de répartir la charge des connexions entre différents processus ou machines, vous devez vous assurer que les demandes associées à un ID de session particulier se connectent au processus qui les a générées.
Cela est dû à certains transports comme le polling XHR ou le polling JSONP qui reposent sur le déclenchement de plusieurs requêtes pendant la durée de vie du "socket". Ne pas activer l'équilibrage collant entraînera la redoutable:
Error during WebSocket handshake: Unexpected response code: 400
Reconfigurez la configuration Nginx comme expliqué puis essayez d'adapter l'Express comme ceci
let port = parseInt(your_port) + parseInt(process.env.NODE_APP_INSTANCE);
server.listen(port, console.log("Server running "+port));
Faites-nous savoir si cela change quelque chose :)
Utilisez une URL sécurisée pour votre connexion initiale, c'est-à-dire au lieu de "http: //" utilisez "https: //". Si le transport WebSocket est choisi, Socket.IO doit également utiliser automatiquement "wss: //" (SSL) pour la connexion WebSocket.
Si vous ne spécifiez aucune URL lorsque vous appelez io (), car il essaie par défaut de se connecter à l'hôte qui sert la page, vous devez fournir une URL ou passer à https
var socket = io.connect('https://localhost', {secure: true}); //remote url
Essayez ces deux méthodes si cela fonctionne pour vous
Essayez cette méthode 1:
J'étais confronté au même problème. Après un débogage de 30 minutes, j'ai résolu le problème en activant l'adhésivité ALB (Application Load Balancer). Ça a marché pour moi.
Essayez cette méthode 2:
// Client side adding transport param:
var socket = io('http://localhost:3000', { transports: ['websocket'] });
Vous pouvez définir cette valeur ' http: // localhost: 30 ' selon votre domaine.