Відмінності між socket.io та websockets


459

Які відмінності між socket.io та websockets у node.js?
Вони обидві технології натискання сервера? Єдині відмінності, які я відчував,

  1. socket.io дозволив мені надсилати / випромінювати повідомлення, вказавши назву події.

  2. У випадку з socket.io повідомлення з сервера надійде на всіх клієнтів, але для того ж у websockets я був змушений зберігати масив усіх з'єднань і проходити через нього, щоб надсилати повідомлення всім клієнтам.

Також мені цікаво, чому веб-інспектори (наприклад, Chrome / firebug / fiddler) не в змозі вловлювати ці повідомлення (з socket.io/websocket) з сервера?

Будь ласка, уточніть це.


6
Що стосується того, чому веб-інспектори не вловлюють трафік: див. Як переглянути вміст запиту WS / WSS Websocket за допомогою Firebug чи іншого?
treaz

1
@treaz вам не потрібна Firebug або щось інше. Розробники Chrome показують підключення WS на вкладці мереж.

Перевірте це (не впевнений, чи є останнім) - educba.com/websocket-vs-socket-io
Manohar Reddy Poreddy

Відповіді:


326

Його переваги полягають у тому, що це спрощує використання WebSockets, як ви описали у №2, і, мабуть, ще важливіше, що він дає збої в інших протоколах у випадку, якщо WebSockets не підтримується у веб-переглядачі чи сервері. Я б уникнув використання WebSockets безпосередньо, якщо ви не дуже добре знайомі з тим, в яких середовищах вони не працюють, і ви здатні подолати ці обмеження.

Це добре читається як у WebSockets, так і в Socket.IO.

http://davidwalsh.name/websocket


63
Socket.IO не будується на версії WebSockets, він просто використовує цю технологію, коли вона доступна.
moka

24
Семантична різниця, і я пояснив, що в решті відповіді, але я оновив відповідь, щоб це відобразити.
Тимофій Стримп

1
@moka, з ваших слів можна зробити висновок, що наступне твердження неправильне? Socket.IO насправді більше, ніж шар над WebSockets.
Пулак Канті Бхаттачарія

3
@PulakKantiBhattacharyya ви можете, будь ласка, вкажіть, на яке твердження ви конкретно маєте на увазі? Socket.IO - це набагато більше, ніж просто шар над WebSockets, він має різну семантику (позначає повідомлення іменем) і робить відмову від різних протоколів, а також має механізм серцебиття. Більше до цього додає ідентифікатори клієнтам на стороні сервера тощо. Тож це не просто обгортка, це повнофункціональна бібліотека. Насправді він не підтримується добре останніми роками, тому я рекомендував би використовувати SockJS, що є значно кращою та більш доглянутою альтернативою Socket.IO.
мока

4
@moka Місяць тому я погодився б з тобою. Socket.io 1.0 зараз не працює і отримує оновлення.
Тимофій Стримп

536

Помилкові уявлення

Існує кілька поширених помилок щодо WebSocket та Socket.IO:

  1. Перша помилкова думка полягає в тому, що використовувати Socket.IO значно простіше, ніж використовувати WebSocket, що, здається, не так. Дивіться приклади нижче.

  2. Друга помилкова думка полягає в тому, що WebSocket не широко підтримується в браузерах. Дивіться нижче для отримання додаткової інформації.

  3. Третя помилкова думка полягає в тому, що Socket.IO погіршує з’єднання як резервне використання у старих браузерах. Він фактично передбачає, що браузер старий і запускає AJAX-з'єднання з сервером, яке згодом оновлюється в браузерах, що підтримують WebSocket, після обміну деяким трафіком. Детальніше дивіться нижче.

Мій експеримент

Я написав модуль npm, щоб продемонструвати різницю між WebSocket і Socket.IO:

Це простий приклад коду на стороні сервера та на стороні клієнта - клієнт підключається до сервера за допомогою WebSocket або Socket.IO, а сервер надсилає три повідомлення з інтервалом в 1s, які додаються до DOM клієнтом.

На стороні сервера

Порівняйте на прикладі сервера приклад використання WebSocket і Socket.IO, щоб зробити те саме в додатку Express.js:

WebSocket Server

Приклад сервера WebSocket за допомогою 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');

Джерело: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.js

Сервер Socket.IO

Приклад сервера Socket.IO за допомогою 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');

Джерело: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.js

Клієнтська сторона

Порівняйте клієнтський приклад використання WebSocket і Socket.IO, щоб зробити те саме в браузері:

Клієнт WebSocket

Приклад клієнта WebSocket за допомогою ванільного 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); });

Джерело: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.html

Socket.IO Клієнт

Приклад клієнта Socket.IO за допомогою ванільного 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); });

Джерело: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.html

Мережевий трафік

Щоб побачити різницю в мережевому трафіку, ви можете запустити мій тест . Ось результати, які я отримав:

Результати WebSocket

2 запити, 1,50 Кб, 0,05 с

З цих 2 запитів:

  1. Сама сторінка HTML
  2. оновлення підключення до WebSocket

(Запит на оновлення з'єднання видно на інструментах розробника з відповіддю 101 протоколів комутації.)

Socket.IO Результати

6 запитів, 181,56 Кб, 0,25 с

З цих 6 запитів:

  1. сама HTML-сторінка
  2. JavaScript Socket.IO (180 кілобайт)
  3. перший запит на довгий опитування AJAX
  4. другий довгий запит на опитування AJAX
  5. третій тривалий запит на опитування AJAX
  6. оновлення підключення до WebSocket

Скріншоти

Результати WebSocket, які я отримав у localhost:

Результати WebSocket - модуль websocket-vs-socket.io

Результати Socket.IO, які я отримав у localhost:

Результати Socket.IO - модуль websocket-vs-socket.io

Перевірте себе

Швидкий старт:

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

Відкрийте http: // localhost: 3001 / у своєму браузері, відкрийте інструменти для розробників за допомогою Shift + Ctrl + I, відкрийте вкладку «Мережа» та перезавантажте сторінку за допомогою Ctrl + R, щоб побачити мережевий трафік для версії WebSocket.

Відкрийте http: // localhost: 3002 / у своєму браузері, відкрийте інструменти для розробників за допомогою Shift + Ctrl + I, відкрийте вкладку «Мережа» та перезавантажте сторінку за допомогою Ctrl + R, щоб побачити мережевий трафік для версії Socket.IO.

Щоб видалити:

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

Сумісність браузера

Станом на червень 2016 року WebSocket працює над усім, крім Opera Mini, включаючи IE вище 9.

Це сумісність веб-переглядача WebSocket в Чи можу я використовувати з червня 2016 року:

введіть тут опис зображення

Дивіться http://caniuse.com/websockets для отримання актуальної інформації.


23
Отже, в основному, що ви говорите, це те, що websocket краще, ніж socket.io?
Джек Москові

42
@JackMoscovi Я б не сказав, що WebSocket - це обов'язково краще. Все залежить від вимог. Переваги WebSocket полягають у тому, що це веб-стандарт (спочатку під W3C та whatwg, тепер під IETF, з RFC, опублікований 5 років тому), він дуже легкий, оскільки його підтримують браузери, але підтримка браузера при хорошій не універсальний. Socket.IO підтримує більше веб-переглядачів і має більше функціональних можливостей, але також має деякі накладні витрати. Іноді одне краще, інше інше. Це як вибір між querySelectorAll та jQuery - відповідь не завжди однакова
rsp

20
Чудова відповідь тут !! Мені здається, socket.io у багатьох випадках більше не потрібен ... Дивіться і цю чудову статтю! medium.com/@ivanderbyl/…
Альваро

4
@rsp Я не думаю, що ці приклади є функціонально еквівалентними? Socket-io обробляє такі речі, як автоматичне відновлення під час перерви (що відбувається на мобільних пристроях), і я думаю, що навколо тих проблем, з якими обробляються, є проблеми безпеки? Ваші прості приклади WS, хоча вони функціонально еквівалентні, не мають цих властивостей.
mindplay.dk

28
Дуже хороше порівняння. Однак варто відзначити, що Socket.io додає інтервал між іменами кімнати, тоннами деталей з'єднання, безліччю деталей ведення журналів, а також є багато бібліотек інтеграції для Socket.IO з Angular, Vue, React та іншими. Найголовніше, що ви можете відключити довгий опитування Ajax і безпосередньо підключитися через WebSocket так само, як і необмежене з'єднання WebSocket. Таким чином ви отримуєте все, крім бібліотеки 180 кбіт, як рівну. Використання WebSocket безпосередньо болюче, якщо вам просто не потрібен мінімум. Затримка приміщень та доступ до ІС громади непростий для підприємства.
Нік Стіл

30

Я надам аргумент проти використання socket.io.

Я думаю, що використання socket.io виключно тому, що у нього є резервні копії - це не дуже гарна ідея. Нехай IE8 RIP.

У минулому було багато випадків, коли нові версії NodeJS зламали socket.io. Ви можете перевірити ці списки на приклади ... https://github.com/socketio/socket.io/isissue?q=install+error

Якщо ви розробляєте додаток для Android або щось, що потрібно співпрацювати з вашим наявним додатком, ви, ймовірно, відразу працюєте з WS, socket.io може доставити вам там проблеми ...

Плюс модуль WS для Node.JS у користуванні надзвичайно простий.


що ви пропонуєте використовувати для взаємодії з mysql -> express.js / fastify.js або node.js безпосередньо ... для створення додатків для чатів для Android та ios
DragonFire

25

Використання Socket.IO в основному схоже на використання jQuery - ви хочете підтримувати старі браузери, вам потрібно написати менше коду, і бібліотека забезпечить резервні копії. Socket.io використовує технологію websockets, якщо вона є, а якщо ні, перевіряє найкращий доступний тип зв'язку та використовує його.


3

Навіть якщо сучасні браузери підтримують WebSockets зараз, я вважаю, що немає необхідності викидати SocketIO, і він все ще має своє місце в будь-якому проекті, що нині працює. Це легко зрозуміти, і особисто я дізнався, як WebSockets працюють завдяки SocketIO.

Як сказано в цій темі, існує велика кількість інтеграційних бібліотек для Angular, React тощо та типів визначення для TypeScript та інших мов програмування.

Інший момент, який я хотів би додати до відмінностей між Socket.io та WebSockets, полягає в тому, що кластеризація з Socket.io не є великою справою. Socket.io пропонує адаптери, які можна використовувати для зв'язку з Redis для підвищення масштабованості. Наприклад, у вас є ioredis і socket.io-redis .

Так, я знаю, SocketCluster існує, але це поза темою.


2

Socket.IO використовує WebSocket, а коли WebSocket недоступний, використовує резервне альго для з'єднання в режимі реального часу.


0

https://socket.io/docs/#What-Socket-IO-is-not (з моїм акцентом )

Що Socket.IO - ні

Socket.IO НЕ є реалізацією WebSocket. Хоча Socket.IO дійсно використовує WebSocket як транспорт, коли це можливо, він додає деякі метадані до кожного пакету: тип пакету, простір імен та ідентифікатор пакета, коли потрібне підтвердження повідомлення. Ось чому клієнт WebSocket не буде зможе успішно підключитися до сервера Socket.IO , а клієнт Socket.IO також не зможе підключитися до сервера WebSocket . Будь ласка, дивіться специфікацію протоколу тут .

// WARNING: the client will NOT be able to connect!
const client = io('ws://echo.websocket.org');
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.