Unterschiede zwischen socket.io und websockets

459

Was sind die Unterschiede zwischen socket.io und websockets in node.js?
Sind beide Server-Push-Technologien? Die einzigen Unterschiede, die ich fühlte, waren:

  1. Mit socket.io konnte ich Nachrichten durch Angabe eines Ereignisnamens senden / senden.

  2. Im Fall von socket.io wird eine Nachricht vom Server auf allen Clients erreicht, aber für dasselbe in Websockets war ich gezwungen, ein Array aller Verbindungen beizubehalten und es zu durchlaufen, um Nachrichten an alle Clients zu senden.

Ich frage mich auch, warum Webinspektoren (wie Chrome / Firebug / Fiddler) diese Nachrichten (von socket.io/websocket) nicht vom Server abfangen können.

Bitte klären Sie dies.

Vivek Mohan
quelle
6
Informationen dazu, warum Webinspektoren
Treaz
1
@treaz du brauchst keinen Firebug oder irgendetwas anderes. Die Devtools von Chrome zeigen WS-Verbindungen auf der Registerkarte "Netzwerke" an.
Überprüfen Sie dies auch (nicht sicher, ob dies aktuell ist) - Educba.com/websocket-vs-socket-io
Manohar Reddy Poreddy

Antworten:

326

Seine Vorteile sind, dass es die Verwendung von WebSockets vereinfacht, wie Sie in # 2 beschrieben haben, und wahrscheinlich noch wichtiger ist, dass es Failover für andere Protokolle bietet, falls WebSockets vom Browser oder Server nicht unterstützt werden. Ich würde es vermeiden, WebSockets direkt zu verwenden, es sei denn, Sie kennen die Umgebungen, in denen sie nicht funktionieren, und Sie sind in der Lage, diese Einschränkungen zu umgehen.

Dies ist eine gute Lektüre sowohl für WebSockets als auch für Socket.IO.

http://davidwalsh.name/websocket

Timothy Strimple
quelle
63
Socket.IO baut nicht auf WebSockets auf, sondern verwendet diese Technologie nur, wenn sie verfügbar ist.
Moka
24
Semantischer Unterschied und ich haben das im Rest der Antwort erklärt, aber ich habe die Antwort aktualisiert, um dies widerzuspiegeln.
Timothy Strimple
1
@moka, kann ich aus deinen Worten schließen, dass die folgende Aussage falsch ist? Socket.IO ist eigentlich mehr als eine Ebene über WebSockets.
Pulak Kanti Bhattacharyya
3
@PulakKantiBhattacharyya Könnten Sie bitte angeben, auf welche Aussage Sie sich genau beziehen? Socket.IO ist weit mehr als nur eine Ebene über WebSockets. Es hat eine unterschiedliche Semantik (markiert Nachrichten mit Namen), führt Failover zu verschiedenen Protokollen durch und verfügt über einen Herzschlagmechanismus. Mehr dazu hängen IDs an Clients auf der Serverseite und mehr. Es handelt sich also nicht nur um einen Wrapper, sondern um eine Bibliothek mit vollem Funktionsumfang. Tatsächlich wurde es in den letzten Jahren nicht gut unterstützt, daher würde ich empfehlen, SockJS zu verwenden, eine viel bessere und besser gewartete Alternative zu Socket.IO.
Moka
4
@moka Vor einem Monat hätte ich dir zugestimmt. Socket.io 1.0 ist ab sofort erhältlich und wird aktualisiert.
Timothy Strimple
536

Missverständnisse

Es gibt nur wenige häufige Missverständnisse in Bezug auf WebSocket und Socket.IO:

  1. Das erste Missverständnis ist, dass die Verwendung von Socket.IO erheblich einfacher ist als die Verwendung von WebSocket, was anscheinend nicht der Fall ist. Siehe Beispiele unten.

  2. Das zweite Missverständnis ist, dass WebSocket in den Browsern nicht allgemein unterstützt wird. Siehe unten für weitere Informationen.

  3. Das dritte Missverständnis ist, dass Socket.IO die Verbindung als Fallback für ältere Browser herunterstuft. Es wird davon ausgegangen, dass der Browser alt ist und eine AJAX-Verbindung zum Server herstellt, die später in Browsern, die WebSocket unterstützen, aktualisiert wird, nachdem ein Teil des Datenverkehrs ausgetauscht wurde. Siehe unten für Details.

Mein Experiment

Ich habe ein npm-Modul geschrieben, um den Unterschied zwischen WebSocket und Socket.IO zu demonstrieren:

Dies ist ein einfaches Beispiel für serverseitigen und clientseitigen Code. Der Client stellt über WebSocket oder Socket.IO eine Verbindung zum Server her und der Server sendet drei Nachrichten in Intervallen von 1 Sekunde, die vom Client zum DOM hinzugefügt werden.

Serverseitig

Vergleichen Sie das serverseitige Beispiel für die Verwendung von WebSocket und Socket.IO, um dasselbe in einer Express.js-App zu tun:

WebSocket Server

Beispiel für einen WebSocket-Server mit 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');

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

Socket.IO Server

Beispiel für einen Socket.IO-Server mit 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');

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

Client-Seite

Vergleichen Sie das clientseitige Beispiel für die Verwendung von WebSocket und Socket.IO, um dasselbe im Browser zu tun:

WebSocket Client

Beispiel für einen WebSocket-Client mit Vanille-JavaScript:

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); });

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

Socket.IO Client

Beispiel für einen Socket.IO-Client mit Vanille-JavaScript:

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); });

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

Netzwerktraffic

Um den Unterschied im Netzwerkverkehr zu sehen, können Sie meinen Test ausführen . Hier sind die Ergebnisse, die ich erhalten habe:

WebSocket-Ergebnisse

2 Anfragen, 1,50 KB, 0,05 s

Aus diesen 2 Anfragen:

  1. HTML-Seite selbst
  2. Verbindungs-Upgrade auf WebSocket

(Die Verbindungsaktualisierungsanforderung wird in den Entwicklertools mit einer Antwort von 101 Switching Protocols angezeigt.)

Socket.IO Ergebnisse

6 Anfragen, 181,56 KB, 0,25 s

Aus diesen 6 Anfragen:

  1. die HTML-Seite selbst
  2. JavaScript von Socket.IO (180 Kilobyte)
  3. erste lange Abfrage AJAX-Anfrage
  4. zweite lange Abfrage AJAX-Anfrage
  5. dritte lange Abfrage AJAX-Anfrage
  6. Verbindungs-Upgrade auf WebSocket

Screenshots

WebSocket-Ergebnisse, die ich auf localhost erhalten habe:

WebSocket-Ergebnisse - Modul websocket-vs-socket.io

Socket.IO Ergebnisse, die ich auf localhost erhalten habe:

Ergebnisse von Socket.IO - Modul websocket-vs-socket.io

Teste dich selbst

Schnellstart:

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

Öffnen Sie http: // localhost: 3001 / in Ihrem Browser, öffnen Sie die Entwicklertools mit Umschalt + Strg + I, öffnen Sie die Registerkarte Netzwerk und laden Sie die Seite mit Strg + R neu, um den Netzwerkverkehr für die WebSocket-Version anzuzeigen.

Öffnen Sie http: // localhost: 3002 / in Ihrem Browser, öffnen Sie die Entwicklertools mit Umschalt + Strg + I, öffnen Sie die Registerkarte Netzwerk und laden Sie die Seite mit Strg + R neu, um den Netzwerkverkehr für die Socket.IO-Version anzuzeigen.

So deinstallieren Sie:

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

Browser-Kompatibilität

Ab Juni 2016 funktioniert WebSocket mit Ausnahme von Opera Mini, einschließlich IE über 9.

Dies ist die Browserkompatibilität von WebSocket für Kann ich ab Juni 2016 verwenden:

Geben Sie hier die Bildbeschreibung ein

Aktuelle Informationen finden Sie unter http://caniuse.com/websockets .

rsp
quelle
23
Sie sagen also im Grunde, dass Websocket besser ist als Socket.io?
Jack Moscovi
42
@ JackMoscovi Ich würde nicht sagen, dass WebSocket unbedingt besser ist. Es hängt alles von den Anforderungen ab. Die Vorteile von WebSocket bestehen darin, dass es sich um einen Webstandard handelt (zuerst unter W3C und whatwg, jetzt unter IETF, mit einem vor 5 Jahren veröffentlichten RFC). Es ist sehr leicht, da es von den Browsern nativ unterstützt wird, die Browserunterstützung jedoch gut ist nicht universell. Socket.IO unterstützt mehr Browser und verfügt über mehr Funktionen, ist jedoch auch mit einem gewissen Overhead verbunden. Manchmal ist einer besser, manchmal der andere. Es ist wie die Wahl zwischen querySelectorAll und jQuery - die Antwort ist nicht immer dieselbe
rsp
20
Tolle Antwort hier !! Es scheint mir, dass socket.io in vielen Fällen nicht mehr notwendig ist ... Siehe auch diesen großartigen Artikel! medium.com/@ivanderbyl/…
Alvaro
4
@rsp Ich denke nicht, dass diese Beispiele funktional gleichwertig sind? Socket-io behandelt Dinge wie die automatische Wiederverbindung bei Unterbrechung (was auf Mobilgeräten passiert) und ich denke, es gibt Sicherheitsbedenken in Bezug auf das, was für Sie behandelt wird? Ihre einfachen WS-Beispiele sind zwar funktional gleichwertig, haben diese Eigenschaften jedoch nicht.
mindplay.dk
28
Sehr guter Vergleich. Es ist jedoch erwähnenswert, dass Socket.io den Raumnamenabstand, unzählige Verbindungsdetails, viele Protokollierungsdetails und zahlreiche Integrationsbibliotheken für Socket.IO mit Angular, Vue, React und anderen hinzufügt. Am wichtigsten ist, dass Sie Ajax Long-Polling deaktivieren und wie bei einer unformatierten WebSocket-Verbindung eine direkte Verbindung über WebSocket herstellen können. Auf diese Weise erhalten Sie alles außer der 180-KB-Bibliothek als gleichwertig. Die direkte Verwendung von WebSocket ist schmerzhaft, es sei denn, Sie benötigen nur das Nötigste. Das Löschen von Räumen und der Zugriff auf die Community-IP ist für Unternehmen entmutigend.
Nick Steele
30

Ich werde ein Argument gegen die Verwendung von socket.io liefern.

Ich denke, die Verwendung von socket.io nur, weil es Fallbacks gibt, ist keine gute Idee. Lassen Sie IE8 RIP.

In der Vergangenheit gab es viele Fälle, in denen neue Versionen von NodeJS socket.io beschädigt haben. Sie können diese Listen auf Beispiele überprüfen ... https://github.com/socketio/socket.io/issues?q=install+error

Wenn Sie eine Android-App entwickeln oder etwas, das mit Ihrer vorhandenen App funktionieren muss, ist es wahrscheinlich in Ordnung, sofort mit WS zu arbeiten. Socket.io kann Ihnen dort Probleme bereiten ...

Außerdem ist das WS-Modul für Node.JS erstaunlich einfach zu bedienen.

Victorio Berra
quelle
Was schlagen Sie vor, um mit mysql -> express.js / fastify.js oder node.js direkt zu interagieren ... um Android- und iOS-Chat-Apps zu
erstellen
25

Die Verwendung von Socket.IO ähnelt im Wesentlichen der Verwendung von jQuery. Sie möchten ältere Browser unterstützen, müssen weniger Code schreiben und die Bibliothek bietet Fallbacks. Socket.io verwendet die Websockets-Technologie, falls verfügbar, und überprüft, falls nicht, den besten verfügbaren Kommunikationstyp und verwendet ihn.

Dev Agrawal
quelle
3

Selbst wenn moderne Browser jetzt WebSockets unterstützen, besteht meiner Meinung nach keine Notwendigkeit, SocketIO wegzuwerfen, und es hat immer noch seinen Platz in einem heutigen Projekt. Es ist leicht zu verstehen und ich persönlich habe dank SocketIO gelernt, wie WebSockets funktionieren.

Wie in diesem Thema erwähnt, gibt es zahlreiche Integrationsbibliotheken für Angular, React usw. und Definitionstypen für TypeScript und andere Programmiersprachen.

Der andere Punkt, den ich zu den Unterschieden zwischen Socket.io und WebSockets hinzufügen möchte, ist, dass das Clustering mit Socket.io keine große Sache ist. Socket.io bietet Adapter an , mit denen es mit Redis verknüpft werden kann, um die Skalierbarkeit zu verbessern. Sie haben zum Beispiel ioredis und socket.io-redis .

Ja, ich weiß, SocketCluster existiert, aber das ist kein Thema.

Maxime Lafarie
quelle
2

Socket.IO verwendet WebSocket. Wenn WebSocket nicht verfügbar ist, wird Fallback-Algo verwendet, um Echtzeitverbindungen herzustellen.

Nitin.
quelle
0

https://socket.io/docs/#What-Socket-IO-is-not (mit meinem Schwerpunkt )

Was Socket.IO nicht ist

Socket.IO ist KEINE WebSocket-Implementierung. Obwohl Socket.IO WebSocket tatsächlich als Transport verwendet, wenn es möglich ist, fügt es jedem Paket einige Metadaten hinzu: den Pakettyp, den Namespace und die Paket-ID, wenn eine Nachrichtenbestätigung benötigt wird. Aus diesem Grund kann ein WebSocket-Client keine erfolgreiche Verbindung zu einem Socket.IO-Server herstellen , und ein Socket.IO-Client kann auch keine Verbindung zu einem WebSocket-Server herstellen . Bitte beachten Sie die Protokollspezifikation hier .

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