Différences entre socket.io et websockets

459

Quelles sont les différences entre socket.io et websockets dans node.js?
S'agit-il de technologies de push de serveur? Les seules différences que j'ai ressenties étaient,

  1. socket.io m'a permis d'envoyer / émettre des messages en spécifiant un nom d'événement.

  2. Dans le cas de socket.io, un message du serveur atteindra tous les clients, mais pour les mêmes dans les websockets, j'ai été obligé de conserver un tableau de toutes les connexions et de le parcourir pour envoyer des messages à tous les clients.

De plus, je me demande pourquoi les inspecteurs Web (comme Chrome / Firebug / Fiddler) ne peuvent pas attraper ces messages (depuis socket.io/websocket) depuis le serveur?

Veuillez clarifier cela.

Vivek Mohan
la source
6
En ce qui concerne les raisons pour lesquelles les inspecteurs Web n'attrapent pas le trafic: voir Comment afficher le contenu de la demande Websocket WS / WSS à l'aide de Firebug ou autre?
treaz
1
@treaz vous n'avez pas besoin de Firebug ou d'autre chose. Les devtools de Chrome affichent les connexions WS sous l'onglet réseaux.
Vérifiez aussi (pas sûr que ce soit le dernier) - educba.com/websocket-vs-socket-io
Manohar Reddy Poreddy

Réponses:

326

Ses avantages sont qu'il simplifie l'utilisation des WebSockets comme vous l'avez décrit dans # 2, et plus important encore, il fournit des basculements vers d'autres protocoles dans le cas où les WebSockets ne sont pas pris en charge sur le navigateur ou le serveur. J'éviterais d'utiliser WebSockets directement à moins que vous ne connaissiez très bien les environnements dans lesquels ils ne fonctionnent pas et que vous soyez capable de contourner ces limitations.

C'est une bonne lecture sur WebSockets et Socket.IO.

http://davidwalsh.name/websocket

Timothy Strimple
la source
63
Socket.IO n'est pas construit sur WebSockets, il utilise simplement cette technologie lorsqu'elle est disponible.
moka
24
Différence sémantique et je l'ai expliqué dans le reste de la réponse, mais j'ai mis à jour la réponse pour refléter cela.
Timothy Strimple
1
@moka, d'après vos mots, puis-je conclure que la déclaration suivante est fausse? Socket.IO est en fait plus qu'une couche sur WebSockets.
Pulak Kanti Bhattacharyya
3
@PulakKantiBhattacharyya pourriez-vous s'il vous plaît spécifier de quelle déclaration vous parlez exactement? Socket.IO est bien plus qu'une simple couche au-dessus de WebSockets, il a une sémantique différente (marque les messages avec le nom) et effectue des basculements vers différents protocoles, ainsi qu'un mécanisme de battement de cœur. Plus à cela attache des ID aux clients côté serveur, et plus encore. Ce n'est donc pas seulement un wrapper, c'est une bibliothèque complète. En fait, il n'a pas été bien pris en charge ces dernières années, donc je recommanderais d'utiliser SockJS qui est une alternative bien meilleure et plus maintenue à Socket.IO.
moka
4
@moka Il y a un mois, je serais d'accord avec vous. Socket.io 1.0 est maintenant disponible et reçoit des mises à jour.
Timothy Strimple
538

Idées fausses

Il existe quelques idées fausses courantes concernant WebSocket et Socket.IO:

  1. La première idée fausse est que l'utilisation de Socket.IO est beaucoup plus facile que l'utilisation de WebSocket, ce qui ne semble pas être le cas. Voir les exemples ci-dessous.

  2. La deuxième idée fausse est que WebSocket n'est pas largement pris en charge dans les navigateurs. Voir ci-dessous pour plus d'informations.

  3. La troisième idée fausse est que Socket.IO rétrograde la connexion en tant que solution de rechange sur les anciens navigateurs. Il suppose en fait que le navigateur est ancien et démarre une connexion AJAX au serveur, qui est ensuite mise à niveau sur les navigateurs prenant en charge WebSocket, après un échange de trafic. Voir ci-dessous pour plus de détails.

Mon expérience

J'ai écrit un module npm pour démontrer la différence entre WebSocket et Socket.IO:

Il s'agit d'un exemple simple de code côté serveur et côté client - le client se connecte au serveur en utilisant WebSocket ou Socket.IO et le serveur envoie trois messages à des intervalles de 1 s, qui sont ajoutés au DOM par le client.

Du côté serveur

Comparez l'exemple côté serveur de l'utilisation de WebSocket et Socket.IO pour faire de même dans une application Express.js:

Serveur WebSocket

Exemple de serveur WebSocket utilisant Express.js:

var path = require('path');
var app = require('express')();
var ws = require('express-ws')(app);
app.get('/', (req, res) => {
  console.error('express connection');
  res.sendFile(path.join(__dirname, 'ws.html'));
});
app.ws('/', (s, req) => {
  console.error('websocket connection');
  for (var t = 0; t < 3; t++)
    setTimeout(() => s.send('message from server', ()=>{}), 1000*t);
});
app.listen(3001, () => console.error('listening on http://localhost:3001/'));
console.error('websocket example');

Source: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.js

Serveur Socket.IO

Exemple de serveur Socket.IO utilisant Express.js:

var path = require('path');
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', (req, res) => {
  console.error('express connection');
  res.sendFile(path.join(__dirname, 'si.html'));
});
io.on('connection', s => {
  console.error('socket.io connection');
  for (var t = 0; t < 3; t++)
    setTimeout(() => s.emit('message', 'message from server'), 1000*t);
});
http.listen(3002, () => console.error('listening on http://localhost:3002/'));
console.error('socket.io example');

Source: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.js

Côté client

Comparez l'exemple côté client d'utilisation de WebSocket et Socket.IO pour faire de même dans le navigateur:

Client WebSocket

Exemple de client WebSocket utilisant JavaScript vanilla:

var l = document.getElementById('l');
var log = function (m) {
    var i = document.createElement('li');
    i.innerText = new Date().toISOString()+' '+m;
    l.appendChild(i);
}
log('opening websocket connection');
var s = new WebSocket('ws://'+window.location.host+'/');
s.addEventListener('error', function (m) { log("error"); });
s.addEventListener('open', function (m) { log("websocket connection open"); });
s.addEventListener('message', function (m) { log(m.data); });

Source: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.html

Client Socket.IO

Exemple de client Socket.IO utilisant JavaScript vanilla:

var l = document.getElementById('l');
var log = function (m) {
    var i = document.createElement('li');
    i.innerText = new Date().toISOString()+' '+m;
    l.appendChild(i);
}
log('opening socket.io connection');
var s = io();
s.on('connect_error', function (m) { log("error"); });
s.on('connect', function (m) { log("socket.io connection open"); });
s.on('message', function (m) { log(m); });

Source: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.html

Trafic réseau

Pour voir la différence de trafic réseau, vous pouvez exécuter mon test . Voici les résultats que j'ai obtenus:

Résultats WebSocket

2 requêtes, 1.50 KB, 0.05 s

De ces 2 demandes:

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

(La demande de mise à niveau de connexion est visible sur les outils de développement avec une réponse 101 Switching Protocols.)

Résultats Socket.IO

6 requêtes, 181.56 KB, 0.25 s

De ces 6 demandes:

  1. la page HTML elle-même
  2. JavaScript de Socket.IO (180 kilo-octets)
  3. première requête AJAX longue interrogation
  4. deuxième requête AJAX longue interrogation
  5. troisième requête AJAX longue interrogation
  6. mise à niveau de la connexion à WebSocket

Captures d'écran

Résultats WebSocket que j'ai obtenus sur localhost:

Résultats WebSocket - module websocket-vs-socket.io

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

Résultats Socket.IO - module websocket-vs-socket.io

Testez-vous

Démarrage rapide:

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

Ouvrez http: // localhost: 3001 / dans votre navigateur, ouvrez les outils de développement avec Shift + Ctrl + I, ouvrez l'onglet Réseau et rechargez la page avec Ctrl + R pour voir le trafic réseau pour la version WebSocket.

Ouvrez http: // localhost: 3002 / dans votre navigateur, ouvrez les outils de développement avec Shift + Ctrl + I, ouvrez l'onglet Réseau et rechargez la page avec Ctrl + R pour voir le trafic réseau pour la version Socket.IO.

Pour désinstaller:

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

Compatibilité du navigateur

Depuis juin 2016, WebSocket fonctionne sur tout sauf Opera Mini, y compris IE supérieur à 9.

Il s'agit de la compatibilité du navigateur WebSocket sur Can I Use à partir de juin 2016:

entrez la description de l'image ici

Voir http://caniuse.com/websockets pour des informations à jour.

rsp
la source
23
Donc, fondamentalement, ce que vous dites, c'est que websocket est meilleur que socket.io?
Jack Moscovi
42
@JackMoscovi Je ne dirais pas que WebSocket est nécessairement meilleur. Tout dépend des exigences. Les avantages de WebSocket sont qu'il s'agit d'un standard Web (d'abord sous W3C et whatwg, maintenant sous IETF, avec un RFC publié il y a 5 ans), il est très léger car il est pris en charge nativement par les navigateurs, mais le support du navigateur tout en étant bon est pas universel. Socket.IO prend en charge plus de navigateurs et a plus de fonctionnalités, mais est également livré avec des frais généraux. Parfois, l'un est meilleur, parfois l'autre. C'est comme choisir entre querySelectorAll et jQuery - la réponse n'est pas toujours la même
rsp
20
Grande réponse ici !! Il me semble que socket.io n'est plus nécessaire dans de nombreux cas ... Voir aussi ce grand article! medium.com/@ivanderbyl/…
Alvaro
4
@rsp Je ne pense pas que ces exemples soient fonctionnellement équivalents? Socket-io gère des choses comme la reconnexion automatique en cas d'interruption (ce qui se produit sur les appareils mobiles) et je pense qu'il y a des problèmes de sécurité autour de ce qui est géré pour vous? Vos exemples WS simples, bien que fonctionnellement équivalents, n'ont pas ces propriétés.
mindplay.dk
28
Très bonne comparaison. Cependant, il convient de noter que Socket.io ajoute l'espacement des noms de pièce, des tonnes de détails de connexion, de nombreux détails de journalisation et il existe de nombreuses bibliothèques d'intégration pour Socket.IO avec Angular, Vue, React et autres. Plus important encore, vous pouvez désactiver l'interrogation longue Ajax et vous connecter directement via WebSocket comme une connexion WebSocket brute. De cette façon, vous obtenez tout sauf la bibliothèque de 180 Ko comme des égaux. L'utilisation directe de WebSocket est pénible, sauf si vous avez juste besoin du strict minimum. L'abandon des salles et l'accès à l'IP communautaire est intimidant pour les entreprises.
Nick Steele
30

Je vais fournir un argument contre l'utilisation de socket.io.

Je pense que l'utilisation de socket.io uniquement parce qu'il a des solutions de repli n'est pas une bonne idée. Laissez IE8 RIP.

Dans le passé, il y a eu de nombreux cas où de nouvelles versions de NodeJS ont cassé socket.io. Vous pouvez consulter ces listes pour des exemples ... https://github.com/socketio/socket.io/issues?q=install+error

Si vous allez développer une application Android ou quelque chose qui doit fonctionner avec votre application existante, vous seriez probablement d'accord avec WS tout de suite, socket.io pourrait vous poser quelques problèmes là-bas ...

De plus, le module WS pour Node.JS est incroyablement simple à utiliser.

Victorio Berra
la source
que proposez-vous que nous utilisions pour interagir avec mysql -> express.js / fastify.js ou node.js directement ... pour créer des applications de chat Android et
iOS
25

Utiliser Socket.IO est fondamentalement comme utiliser jQuery - vous voulez prendre en charge les navigateurs plus anciens, vous devez écrire moins de code et la bibliothèque fournira des solutions de secours. Socket.io utilise la technologie websockets si elle est disponible, et sinon, vérifie le meilleur type de communication disponible et l'utilise.

Dev Agrawal
la source
3

Même si les navigateurs modernes prennent en charge WebSockets maintenant, je pense qu'il n'est pas nécessaire de jeter SocketIO et il a toujours sa place dans n'importe quel projet de nos jours. C'est facile à comprendre et personnellement, j'ai appris comment fonctionnent les WebSockets grâce à SocketIO.

Comme indiqué dans cette rubrique, il existe de nombreuses bibliothèques d'intégration pour Angular, React, etc. et des types de définition pour TypeScript et d'autres langages de programmation.

L'autre point que j'ajouterais aux différences entre Socket.io et WebSockets est que le clustering avec Socket.io n'est pas un gros problème. Socket.io propose des adaptateurs qui peuvent être utilisés pour le relier à Redis afin d'améliorer l'évolutivité. Vous avez par exemple ioredis et socket.io-redis .

Oui, je sais, SocketCluster existe, mais c'est hors sujet.

Maxime Lafarie
la source
2

Socket.IO utilise WebSocket et lorsque WebSocket n'est pas disponible utilise algo de secours pour établir des connexions en temps réel.

Nitine.
la source
0

https://socket.io/docs/#What-Socket-IO-is-not (avec mon accent )

Ce que Socket.IO n'est pas

Socket.IO n'est PAS une implémentation WebSocket. Bien que Socket.IO utilise en effet WebSocket comme transport lorsque cela est possible, il ajoute des métadonnées à chaque paquet: le type de paquet, l'espace de noms et l'ID de paquet lorsqu'un accusé de réception de message est nécessaire. C'est pourquoi un client WebSocket ne pourra pas se connecter avec succès à un serveur Socket.IO et un client Socket.IO ne pourra pas non plus se connecter à un serveur WebSocket . Veuillez consulter la spécification du protocole ici .

// WARNING: the client will NOT be able to connect!
const client = io('ws://echo.websocket.org');
Ken Lin
la source