Различия между socket.io и websockets

459

Каковы различия между socket.io и websockets в node.js?
Они обе - серверные технологии? Единственные различия, которые я чувствовал, были,

  1. socket.io позволял мне отправлять / отправлять сообщения, указав имя события.

  2. В случае socket.io сообщение от сервера будет поступать на все клиенты, но для того же самого в веб-сокетах я был вынужден хранить массив всех соединений и проходить через него для отправки сообщений всем клиентам.

Кроме того, мне интересно, почему веб-инспекторы (такие как Chrome / firebug / fiddler) не могут перехватить эти сообщения (из socket.io/websocket) с сервера?

Пожалуйста, уточните это.

Вивек Мохан
источник
6
Относительно того, почему веб-инспекторы не улавливают трафик: см. Как просмотреть содержимое запроса веб-сокета WS / WSS с помощью Firebug или другого?
Treaz
1
@treaz вам не нужен Firebug или что-то еще. Devtools в Chrome показывают WS-соединения на вкладке сети.
Проверьте это тоже (не уверен, что это последнее) - educba.com/websocket-vs-socket-io
Манохар Редди Poreddy

Ответы:

326

Его преимущества заключаются в том, что он упрощает использование WebSockets, как вы описали в # 2, и, возможно, что более важно, он обеспечивает отработки отказа для других протоколов в случае, если WebSockets не поддерживаются в браузере или на сервере. Я бы не стал использовать WebSockets напрямую, если вы не очень хорошо знаете, в каких средах они не работают, и не способны обойти эти ограничения.

Это хорошее чтение как для WebSockets, так и для Socket.IO.

http://davidwalsh.name/websocket

Тимоти Стрипл
источник
63
Socket.IO не построен поверх WebSockets, он просто использует эту технологию, когда она доступна.
Мока
24
Семантическая разница, и я объяснил это в остальной части ответа, но я обновил ответ, чтобы отразить это.
Тимоти Стриппл
1
@moka, из твоих слов я могу сделать вывод, что следующее утверждение неверно? Socket.IO - это больше, чем слой над WebSockets.
Пулак Канти Бхаттачарья
3
@PulakKantiBhattacharyya, не могли бы вы уточнить, какое именно заявление вы имеете в виду? Socket.IO - это нечто большее, чем просто слой над WebSockets, он имеет различную семантику (помечает сообщения именем) и выполняет отработку отказа для разных протоколов, а также механизм биения. Более того, это прикрепляет идентификаторы к клиентам на стороне сервера и многое другое. Так что это не просто обертка, это полнофункциональная библиотека. Фактически, в последние годы это не получило хорошей поддержки, поэтому я бы порекомендовал использовать SockJS, который является лучшей и более удобной альтернативой Socket.IO.
Мока
4
@moka Месяц назад я бы с тобой согласился. Socket.io 1.0 вышел и получает обновления.
Тимоти Стриппл
538

заблуждения

Существует несколько распространенных заблуждений относительно WebSocket и Socket.IO:

  1. Первое заблуждение заключается в том, что использовать Socket.IO значительно проще, чем использовать WebSocket, что, похоже, не так. Смотрите примеры ниже.

  2. Второе заблуждение заключается в том, что WebSocket не широко поддерживается в браузерах. Смотрите ниже для получения дополнительной информации.

  3. Третье заблуждение заключается в том, что Socket.IO снижает версию соединения как запасной вариант в старых браузерах. Фактически предполагается, что браузер устарел и устанавливает AJAX-соединение с сервером, которое впоследствии обновляется в браузерах, поддерживающих WebSocket, после обмена некоторым трафиком. Смотрите ниже для деталей.

Мой эксперимент

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

Это простой пример кода на стороне сервера и на стороне клиента: клиент подключается к серверу с помощью WebSocket или Socket.IO, а сервер отправляет три сообщения с интервалом в 1 с, которые клиент добавляет в 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 Switching Protocols.)

Результаты 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 для получения актуальной информации.

RSP
источник
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 напрямую является болезненным, если только вам не нужен минимум. Увольнение комнат и доступ к сообществу IP является пугающим для предприятия.
Ник Стил
30

Я собираюсь предоставить аргумент против использования socket.io.

Я думаю, что использование socket.io исключительно потому, что у него есть запасные варианты, не очень хорошая идея. Пусть IE8 RIP.

В прошлом было много случаев, когда новые версии NodeJS ломали socket.io. Вы можете проверить эти списки для примеров ... https://github.com/socketio/socket.io/issues?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 использует технологию веб-сокетов, если она доступна, а если нет, проверяет наилучший доступный тип связи и использует ее.

Дев Агравал
источник
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');
Кен Лин
источник