Różnice między socket.io a websockets

459

Jakie są różnice między socket.io i websockets w node.js?
Czy oba są technologiami wypychania serwerów? Jedyne różnice, które czułem, to:

  1. gniazdo.io pozwoliło mi wysyłać / emitować wiadomości, podając nazwę zdarzenia.

  2. W przypadku socket.io wiadomość z serwera dotrze do wszystkich klientów, ale dla tego samego w websockets byłem zmuszony zachować tablicę wszystkich połączeń i przejść przez nią pętlę, aby wysłać wiadomości do wszystkich klientów.

Zastanawiam się także, dlaczego inspektorzy sieci (np. Chrome / firebug / fiddler) nie są w stanie przechwycić tych wiadomości (z socket.io/websocket) z serwera?

Proszę to wyjaśnić.

Vivek Mohan
źródło
6
Jeśli chodzi o to, dlaczego inspektorzy sieci nie wychwytują
treaz
1
@treaz nie potrzebujesz Firebug ani niczego innego. Devtools Chrome pokazują połączenia WS na karcie sieci.
To też sprawdź (nie jestem pewien, czy to jest najnowsze) - educba.com/websocket-vs-socket-io
Manohar Reddy Poreddy

Odpowiedzi:

326

Jego zalety polegają na tym, że upraszcza korzystanie z WebSockets, jak opisano w punkcie 2, i co ważniejsze, zapewnia przełączanie awaryjne na inne protokoły w przypadku, gdy WebSockets nie są obsługiwane w przeglądarce lub na serwerze. Unikałbym bezpośredniego korzystania z WebSockets, chyba że dobrze znasz środowiska, w których one nie działają i jesteś w stanie obejść te ograniczenia.

To dobry odczyt zarówno na WebSockets, jak i Socket.IO.

http://davidwalsh.name/websocket

Timothy Strimple
źródło
63
Socket.IO nie jest oparty na WebSockets, po prostu korzysta z tej technologii, gdy jest dostępna.
moka
24
Różnica semantyczna i wyjaśniłem to w pozostałej części odpowiedzi, ale zaktualizowałem odpowiedź, aby to odzwierciedlić.
Timothy Strimple
1
@moka, czy na podstawie twoich słów mogę stwierdzić, że poniższe stwierdzenie jest nieprawidłowe? Socket.IO jest w rzeczywistości czymś więcej niż warstwą nad WebSockets.
Pulak Kanti Bhattacharyya
3
@PulakKantiBhattacharyya czy mógłbyś podać, do którego oświadczenia dokładnie się odnosisz? Socket.IO jest czymś więcej niż tylko warstwą nad WebSockets, ma inną semantykę (oznacza wiadomości za pomocą nazwy) i przełącza awaryjnie do różnych protokołów, a także ma mechanizm bicia serca. Ponadto dołącza identyfikatory do klientów po stronie serwera i nie tylko. Więc to nie jest tylko opakowanie, to w pełni funkcjonalna biblioteka. W rzeczywistości nie był dobrze obsługiwany w ostatnich latach, dlatego poleciłbym użyć SockJS, który jest znacznie lepszą i lepiej utrzymaną alternatywą dla Socket.IO.
moka
4
@moka Miesiąc temu zgodziłbym się z tobą. Socket.io 1.0 jest już dostępny i otrzymuje aktualizacje.
Timothy Strimple,
536

Nieporozumienia

Istnieje kilka typowych nieporozumień dotyczących WebSocket i Socket.IO:

  1. Pierwszym nieporozumieniem jest to, że używanie Socket.IO jest znacznie łatwiejsze niż używanie WebSocket, co nie wydaje się być prawdą. Zobacz przykłady poniżej.

  2. Drugim nieporozumieniem jest to, że WebSocket nie jest szeroko obsługiwany w przeglądarkach. Zobacz więcej informacji.

  3. Trzecie nieporozumienie polega na tym, że Socket.IO obniża połączenie jako awarię starszych przeglądarek. Zakłada, że ​​przeglądarka jest stara i uruchamia połączenie AJAX z serwerem, które później jest uaktualniane w przeglądarkach obsługujących WebSocket, po wymianie ruchu. Szczegóły poniżej.

Mój eksperyment

Napisałem moduł npm, aby zademonstrować różnicę między WebSocket a Socket.IO:

Jest to prosty przykład kodu po stronie serwera i po stronie klienta - klient łączy się z serwerem za pomocą WebSocket lub Socket.IO, a serwer wysyła trzy komunikaty w odstępach 1s, które są dodawane do DOM przez klienta.

Po stronie serwera

Porównaj przykład użycia serwera WebSocket i Socket.IO do wykonania tego samego w aplikacji Express.js:

Serwer WebSocket

Przykład serwera WebSocket przy użyciu 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');

Źródło: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.js

Serwer Socket.IO

Przykład serwera Socket.IO przy użyciu 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');

Źródło: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.js

Strona klienta

Porównaj przykład użycia klienta WebSocket i Socket.IO do zrobienia tego samego w przeglądarce:

Klient WebSocket

Przykład klienta WebSocket z waniliowym 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); });

Źródło: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.html

Klient Socket.IO

Przykład klienta Socket.IO przy użyciu waniliowego 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); });

Źródło: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.html

Ruch sieciowy

Aby zobaczyć różnicę w ruchu sieciowym, możesz uruchomić mój test . Oto wyniki, które otrzymałem:

Wyniki WebSocket

2 żądania, 1,50 KB, 0,05 s

Z tych 2 wniosków:

  1. Sama strona HTML
  2. aktualizacja połączenia do WebSocket

(Żądanie aktualizacji połączenia jest widoczne w narzędziach programisty z odpowiedzią 101 Protokoły przełączające.)

Wyniki Socket.IO

6 wniosków, 181,56 KB, 0,25 s

Z tych 6 wniosków:

  1. sama strona HTML
  2. JavaScript Socket.IO (180 kilobajtów)
  3. pierwsze długie żądanie AJAX z odpytywaniem
  4. drugie długie żądanie AJAX z przepytywaniem
  5. trzecie długie żądanie AJAX z odpytywaniem
  6. aktualizacja połączenia do WebSocket

Zrzuty ekranu

Wyniki WebSocket, które otrzymałem na localhost:

Wyniki WebSocket - moduł websocket-vs-socket.io

Wyniki Socket.IO, które dostałem na localhost:

Wyniki Socket.IO - moduł websocket-vs-socket.io

Sprawdź się

Szybki start:

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

Otwórz http: // localhost: 3001 / w przeglądarce, otwórz narzędzia programistyczne za pomocą Shift + Ctrl + I, otwórz kartę Sieć i ponownie załaduj stronę za pomocą Ctrl + R, aby zobaczyć ruch sieciowy dla wersji WebSocket.

Otwórz http: // localhost: 3002 / w przeglądarce, otwórz narzędzia programistyczne za pomocą Shift + Ctrl + I, otwórz kartę Sieć i ponownie załaduj stronę za pomocą Ctrl + R, aby zobaczyć ruch sieciowy dla wersji Socket.IO.

Aby odinstalować:

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

Kompatybilność z przeglądarkami

Od czerwca 2016 WebSocket działa na wszystkim oprócz Opery Mini, w tym IE wyższej niż 9.

Oto kompatybilność przeglądarki WebSocket w Czy mogę używać od czerwca 2016:

wprowadź opis zdjęcia tutaj

Aktualne informacje można znaleźć na stronie http://caniuse.com/websockets .

rsp
źródło
23
Więc zasadniczo mówisz, że websocket jest lepszy niż socket.io?
Jack Moscovi
42
@JackMoscovi Nie powiedziałbym, że WebSocket jest z konieczności lepszy. Wszystko zależy od wymagań. Zaletą WebSocket jest to, że jest standardem internetowym (najpierw pod W3C i whatwg, teraz pod IETF, z RFC opublikowanym 5 lat temu), jest bardzo lekki, ponieważ jest natywnie obsługiwany przez przeglądarki, ale obsługa przeglądarki jest dobra, ale nie uniwersalny. Socket.IO obsługuje więcej przeglądarek i ma większą funkcjonalność, ale ma również pewne koszty ogólne. Czasem jedno jest lepsze, a czasem drugie. To jak wybieranie między querySelectorAll i jQuery - odpowiedź nie zawsze jest taka sama
rsp
20
Świetna odpowiedź tutaj !! Wydaje mi się, że socket.io nie jest już konieczne w wielu przypadkach ... Zobacz także ten świetny artykuł! medium.com/@ivanderbyl/…
Alvaro
4
@rsp Nie wydaje mi się, żeby te przykłady były funkcjonalnie równoważne? Socket-io obsługuje takie rzeczy, jak automatyczne ponowne łączenie po przerwaniu (co dzieje się na urządzeniach mobilnych) i myślę, że istnieją obawy związane z bezpieczeństwem wokół tych, które są obsługiwane dla Ciebie? Twoje proste przykłady WS, choć funkcjonalnie równoważne, nie mają tych właściwości.
mindplay.dk
28
Bardzo dobre porównanie. Warto jednak zauważyć, że Socket.io dodaje odstępy między nazwami pokoi, masę szczegółów połączeń, wiele szczegółów rejestrowania i istnieje wiele bibliotek integracyjnych dla Socket.IO z Angular, Vue, React i innymi. Co najważniejsze, możesz wyłączyć długie odpytywanie Ajax i łączyć się bezpośrednio przez WebSocket, tak jak surowe połączenie WebSocket. W ten sposób otrzymujesz wszystko oprócz biblioteki 180kb jako równe. Bezpośrednie korzystanie z WebSocket jest bolesne, chyba że potrzebujesz absolutnego minimum. Opuszczanie pokoi i dostęp do adresu IP społeczności są trudne dla przedsiębiorstw.
Nick Steele,
30

Zamierzam przedstawić argument przeciwko używaniu socket.io.

Myślę, że używanie socket.io tylko dlatego, że ma awarie, nie jest dobrym pomysłem. Niech IE8 RIP.

W przeszłości było wiele przypadków, w których nowe wersje NodeJS zepsuły socket.io. Możesz sprawdzić te listy w poszukiwaniu przykładów ... https://github.com/socketio/socket.io/issues?q=install+error

Jeśli zdecydujesz się stworzyć aplikację na Androida lub coś, co musi współpracować z istniejącą aplikacją, prawdopodobnie dobrze byłoby pracować z WS od razu, socket.io może sprawić ci problemy ...

Dodatkowo moduł WS dla Node.JS jest niezwykle prosty w użyciu.

Victorio Berra
źródło
co sugerujesz, że używamy do interakcji z mysql -> express.js / fastify.js lub node.js bezpośrednio ... do budowania aplikacji na Androida i iOS
DragonFire
25

Korzystanie z Socket.IO jest w zasadzie podobne do korzystania z jQuery - chcesz obsługiwać starsze przeglądarki, musisz napisać mniej kodu, a biblioteka zapewni awarie. Socket.io korzysta z technologii websockets, jeśli jest dostępna, a jeśli nie, sprawdza najlepszy dostępny rodzaj komunikacji i korzysta z niej.

Dev Agrawal
źródło
3

Nawet jeśli współczesne przeglądarki obsługują teraz WebSockets, myślę, że nie ma potrzeby wyrzucania SocketIO i nadal ma swoje miejsce w każdym współczesnym projekcie. Łatwo to zrozumieć i osobiście nauczyłem się, jak działa WebSockets dzięki SocketIO.

Jak powiedziano w tym temacie, istnieje wiele bibliotek integracyjnych dla Angular, React itp. Oraz typów definicji dla TypeScript i innych języków programowania.

Inną kwestią, którą chciałbym dodać do różnic między Socket.io i WebSockets, jest to, że grupowanie w Socket.io nie jest wielkim problemem. Socket.io oferuje Adaptery , których można użyć do połączenia go z Redis w celu zwiększenia skalowalności. Na przykład masz ioredis i socket.io-redis .

Tak, wiem, SocketCluster istnieje, ale to nie na temat.

Maxime Lafarie
źródło
2

Socket.IO korzysta z WebSocket, a gdy WebSocket nie jest dostępny, używa rezerwowego algorytmu do nawiązywania połączeń w czasie rzeczywistym.

Nitin.
źródło
0

https://socket.io/docs/#What-Socket-IO-is-not (z moim naciskiem )

Czym nie jest Socket.IO

Socket.IO NIE jest implementacją WebSocket. Chociaż Socket.IO rzeczywiście używa WebSocket jako transportu, gdy jest to możliwe, dodaje do każdego pakietu pewne metadane: typ pakietu, przestrzeń nazw i identyfikator pakietu, gdy potrzebne jest potwierdzenie komunikatu. Dlatego klient WebSocket nie będzie mógł połączyć się z serwerem Socket.IO , a klient Socket.IO nie będzie mógł połączyć się z serwerem WebSocket . Zobacz specyfikację protokołu tutaj .

// WARNING: the client will NOT be able to connect!
const client = io('ws://echo.websocket.org');
Ken Lin
źródło