Socket.io 1.x: utilisez WebSockets seulement?

nous développons une application web qui ne fonctionnera que sur les navigateurs modernes (IE10+) pour différentes raisons.

L'une des fonctionnalités que nous avons implémentées est Socket.io 1.x. Cependant, par défaut la Socket.le client io essaie de prendre en charge les navigateurs plus anciens, donc il démarre une connexion avec long polling puis met à jour cela aux WebSockets. C'est une perte de temps et de ressources, étant donné que nous sommes certains que le navigateur supporte WS.

j'ai cherché partout, et je peut seulement trouver cette page wiki qui, cependant, est au sujet de Socket.io 0.9.

finalement, j'ai trouvé la documentation pour le moteur.io-client (sur lequel Socket.io-client est basé sur le 1.x succursale). C'est le code que j'ai écrit et semble à travailler. Cependant, je voudrais savoir si c'est correct ou si je fais quelque chose de mal:

io.connect('https://...', {
    upgrade: false,
    transports: ['websocket']
})

Bizarrement, la seule définition de l' La propriété transports sur un tableau avec websockets n'était pas suffisante; j'ai aussi dû désactiver upgrade . Est-ce correct?

mise à Jour

j'ai fait de nouvelles découvertes.

avec transports défini à ['websocket'] seulement, cela ne fait aucune différence que upgrade soit activé ou non. Est-ce normal?

31
demandé sur ItalyPaleAle 2015-01-30 18:01:14

4 réponses

il existe deux types de" mises à niveau " se produisant avec socket.io. First (in socket.io 1.0+), socket.io démarre toutes les connexions avec une requête de sondage http et il peut en fait échanger quelques données initiales avec une simple requête http. Ensuite, à un certain point après cela, il va essayer de réellement initier une connexion webSocket. la connexion webSocket se fait en envoyant un type particulier de requête http qui spécifie un en-tête upgrade: websocket et le serveur peut alors répondre de manière appropriée. qu'il supporte websocket ou non. Si le serveur accepte la mise à niveau, alors cette connexion http particulière est "mise à niveau" vers le protocole webSocket. À ce moment, le client sait alors que webSocket est pris en charge et il cesse d'utiliser les requêtes http polling, complétant ainsi son upgrade vers webSocket.

vous pouvez empêcher le sondage http initial entièrement en faisant ceci sur le client:

var socket = io({transports: ['websocket'], upgrade: false});

cela empêchera le scrutin des relations de vos propres clients coopérants. Si vous voulez empêcher un client d'utiliser polling, vous pouvez ajouter ceci au serveur:

io.set('transports', ['websocket']);

mais, si vous mettez cela sur le serveur, socket.les clients io qui se connectent initialement avec le sondage http ne fonctionneront pas du tout. Donc, cela ne devrait être apparié avec les bons paramètres dans le client de sorte que le client ne commence jamais avec le sondage.

cela dira aux deux extrémités que vous seulement vous voulez utiliser des webSockets et des sockets.io sautera le sondage http supplémentaire au début. Fair warning, cette opération nécessite la webSocket de soutien de sorte à ce règlement compatible avec les anciennes versions d'IE qui n'a pas encore pris en charge par webSocket. Si vous souhaitez conserver la compatibilité, puis il suffit de laisser prise.io le faire avec un couple de requêtes http à l'origine.


voici plus d'informations sur la mise à niveau du protocole http vers webSocket.

le le protocole webSockets initie chaque webSocket avec une connexion HTTP. C'est comme ça que tous les webSockets fonctionnent. Cette connexion HTTP contient des en-têtes qui indiquent que le navigateur "souhaite" passer au protocole webSockets. Si le serveur supporte ce protocole, alors il répond en disant au client qu'il va passer au protocole webSocket et que la socket passe alors du protocole HTTP au protocole webSocket. C'est ainsi qu'une connexion webSocket est conçu pour travail. Donc, le fait que vous voyez votre connexion webSocket démarrer avec une connexion HTTP est 100% normal.

vous pouvez configurer socket.io À NE JAMAIS utiliser de sondage long si cela vous fait vous sentir mieux, mais cela ne changera pas le fait que la connexion webSocket va toujours commencer avec une connexion HTTP qui est ensuite mis à niveau pour le protocole webSocket et il ne sera pas améliorer l'efficacité de l'opération dans les navigateurs modernes qui prennent en charge les webSockets. Il faudra toutefois faire en sorte que votre connexion ne fonctionne pas dans les navigateurs plus anciens.

47
répondu jfriend00 2016-08-22 22:42:24

pour dire À Douille.IO utilisation de WebSocket seulement, au lieu de quelques demandes XHR d'abord, il suffit d'ajouter à cela le Nœud du serveur:

io.set('transports', ['websocket']);

et sur le client ajouter ceci:

var socket = io({transports: ['websocket']});

raconte Cette Prise.IO à utiliser uniquement protocole WebSocket et rien d'autre; c'est plus propre, plus rapide et utilise un peu moins de ressources sur les côtés client et serveur.

Maintenant, vous ne verrez qu'une seule connexion WebSocket dans votre demande réseau liste, juste garder à l'esprit IE9 et plus tôt ne peut pas utiliser WebSocket.

23
répondu Nick Steele 2015-12-26 01:32:44

je poste cette réponse parce que la réponse acceptée n'est pas correcte - elle confond la Socket.Io upgrade from long-polling AJAX to WebSocket with the WSS protocol "Connection: Upgrade" request. Le problème n'est pas que la connexion WebSocket commence par HTTP et se transforme en WebSocket - comment ne pas le faire? - mais cette prise.IO commence avec une longue connexion AJAX, même sur les navigateurs supportant WebSocket, et ne le met à niveau que plus tard après avoir échangé un peu de trafic. Il est très facile de voir les outils de développement de Firefox ou Chrome.

l'auteur de la question a raison dans ses observations. La" mise à niveau " dans Socket.IO ne fait pas référence à la mise à niveau du protocole HTTP vers WSS comme c'est souvent mal compris, mais à la mise à niveau du Socket.Connexion IO à partir D'une connexion AJAX à long-polling vers WebSocket. Si vous commencez déjà avec WebSocket (ce qui n'est pas le cas par défaut), upgrade false n'a aucun effet car vous n'avez pas besoin de mettre à jour. Si vous commencez avec les sondages et désactivez mise à niveau alors qu'il reste de cette façon et ne fait pas de mise à niveau de WebSocket.

Voir les réponses par arnold et Nick Steele si vous voulez éviter de commencer avec le long du scrutin. Je vais vous expliquer ce qui se passe dans plus de détails.

C'est ce que j'ai observé dans mes expériences avec simple WebSocket et Socket.Io apps:

WebSocket

2 requêtes, 1,50 KB, 0,05 s

de ces 2 requêtes:

  1. page HTML elle-même
  2. mise à niveau de la connexion à WebSocket

(la demande de mise à niveau de la connexion est visible sur les outils de développement avec une réponse 101 protocoles de commutation.)

Socket.IO

6 demandes de, 181.56 KO, 0,25 s

de ces 6 requêtes:

  1. la page HTML elle-même
  2. Socket.Io's JavaScript (180 kilooctets)
  3. first long polling demande AJAX
  4. second long polling demande AJAX
  5. troisième interrogation requête AJAX
  6. mise à niveau de la connexion à WebSocket

détails

résultats de WebSocket que j'ai obtenu sur localhost:

WebSocket results - websocket-vs-socket.io module

Socket.IO résultats que j'ai obtenus sur localhost:

Socket.IO results - websocket-vs-socket.io module

Testez-vous

j'ai publié le code sur npm et sur GitHub , vous pouvez l'exécuter vous-même:

# Install:
npm i -g websocket-vs-socket.io
# Run the server:
websocket-vs-socket.io

et suivre les instrictions. Désinstaller:

# Uninstall:
npm rm -g websocket-vs-socket.io

Voir cette réponse pour plus d'info.

15
répondu rsp 2016-07-25 03:21:53

j'ai pensé que je devrais ajouter à la réponse acceptée ci-dessus, comme si quelqu'un veut éliminer le transport de sondage XHR et lancer des websockets tout de suite. Le code ci-dessous est juste pour donner une idée de la mise en œuvre:

var url = serverUrl + "/ssClients"  //ssClients is the socket.io namespace

var connectionOptions =  {
    "force new connection" : true,
    "reconnection": true,
    "reconnectionDelay": 2000,                  //starts with 2 secs delay, then 4, 6, 8, until 60 where it stays forever until it reconnects
    "reconnectionDelayMax" : 60000,             //1 minute maximum delay between connections
    "reconnectionAttempts": "Infinity",         //to prevent dead clients, having the user to having to manually reconnect after a server restart.
    "timeout" : 10000,                           //before connect_error and connect_timeout are emitted.
    "transports" : ["websocket"]                //forces the transport to be only websocket. Server needs to be setup as well/
}
var socket = require("socket.io-client")(url, connectionOptions); 

socket.on("connect", function (_socket) {
    logger.info("Client connected to server: " + clientName);
    logger.info("Transport being used: " + socket.io.engine.transport.name);

    socket.emit("join", clientName, function(_socketId) {  //tell the server the client name
        logger.info("Client received acknowledgement from server: " + _socketId);
        logger.info("Transport being used after acknowledgement: " + socket.io.engine.transport.name);

    });
});

après la configuration du serveur, vous verrez ceci:

2015-10-23T19:04:30.076Z - info:    Client connected to server: someClientId 
2015-10-23T19:04:30.077Z - info:    Transport being used: websocket 
2015-10-23T19:04:30.081Z - info:    Client received acknowledgement from server: aMH0SmW8CbiL8w5RAAAA
2015-10-23T19:04:30.081Z - info:    Transport being used after acknowledgement: websocket

si vous ne forcez pas le transport, vous verrez "polling" à la place de websocket. Cependant, cela ne se produit pas du côté du client seulement, le serveur doit aussi être configuré:

var io = require("socket.io")(server, { adapter: adapter, log: false }); //attach io to existing Express (http) server
..
io.set('transports', ['websocket']); //forces client to connect as websockets. If client tries xhr polling, it won't connect.

Danger

si le client fait réellement pas supporter le protocole websocket, une connexion ne se produira pas et le client signalera un xhr poll error .

cela fonctionne parfaitement pour moi parce que je peux contrôler les clients que j'ai, donc j'ai le luxe de forcer websockets tout de suite, qui je crois est ce que la question originale est demander. J'espère que cela aide quelqu'un là-bas...

7
répondu arnold 2015-10-23 19:54:03