webSocket (2) короткий опрос, длинный опрос, Websocket, sse

HTTP

Введение

Веб-сокеты определяют способ связи по сети через один сокет.полнодуплексный канал связи. Просто постепенное улучшение по сравнению с традиционной связью HTTP, особенно дляВ режиме реального времени, управляемый событиямиПриложение — это шаг вперед. Путем сравнения Polling (опрос), Long-Polling (длинный опрос), Websocket и sse. Четыре технологии обмена мгновенными сообщениями в Интернете, сравнивающие ихМетод реализацииа такжеПреимущества и недостатки каждого. Сравнительные преимущества и недостатки заключаются в следующем:

# Опрос Долгий опрос Websocket sse
письмо-соглашение http http tcp http
Метод триггера клиент (клиент) клиент (клиент) клиент, сервер (клиент, сервер) клиент, сервер (клиент, сервер)
преимущество Хорошая совместимость, сильная отказоустойчивость, простая реализация Экономит ресурсы по сравнению с коротким опросом Полнодуплексный протокол связи, низкая производительность, высокий уровень безопасности и масштабируемость. Простая реализация и низкая стоимость разработки
недостаток Плохая безопасность, учитывая больше ресурсов памяти и количества запросов Плохая безопасность, занимающая больше ресурсов памяти и запросов Передача данных требует вторичного анализа, что увеличивает стоимость и сложность разработки. Только для продвинутых браузеров
Задерживать Не в режиме реального времени, задержка зависит от интервала запроса то же, что короткий опрос в реальном времени Не в реальном времени, задержка по умолчанию 3 секунды, задержку можно настроить

Вышеупомянутое в основном включает реализацию каждогопреимуществоа такженедостаток, на чем они основаныпротокол, к тому концуинициативаотправить данные.

Опрос

Короткий опрос (опрос)Идея реализациисторона браузеракаждые несколько секунд доСервис-терминалОтправьте http-запрос, и сервер ответит сразу после получения запроса, независимо от того, есть ли обновление данных.Когда ответ сервера будет завершен, соединение TCP будет закрыто.,Как показано ниже:

webSocket

Пример кода реализован следующим образом:

function Polling() {
    fetch(url).then(data => {
        // somthing
    }).catch(err => {
        console.log(err);
    });
}
setInterval(polling, 5000);
  • Преимущества: Как видите, реализация очень проста, еесовместимостьТакже лучше, покаПоддержка http-протоколаможно достичь таким образом.
  • Недостатки: Но очевиден и его недостаток, что он очень сильно потребляет ресурсы, т.к.TcpСоединение очень ресурсоемкое, и сервер закроет его, когда ответ будет завершен.Tcpсоединение, следующий запрос устанавливается сноваTcpсоединять.

COMET

**Алекс Рассел (руководитель проекта Dojo Toolkit)** говорит, что это основано наHTTP长连接, Технология «проталкивания сервера», которая не требует установки плагинов на стороне браузера,“Comet”. Обычно используемые COMET делятся на два типа:Технология длительного опроса на основе HTTP и режим потока с длинным соединением на основе iframe..

Долгий опрос

После того, как клиент отправит запрос, серверне сразуВозвращает данные, сервер будетзапрос на блокировкусоединение не будетОтключить немедленно, пока на стороне сервераОбновление данных или тайм-аут соединенияТолько после возвращения клиент снова отправляет запрос на создание нового соединения и так далее для получения последних данных. Общий эффект таков:

webSocket

Код клиента выглядит следующим образом:

function LongPolling() {
    fetch(url).then(data => {
        LongPolling();
    }).catch(err => {
        LongPolling();
        console.log(err);
    });
}
LongPolling();
  • Преимущества: по сравнению с коротким опросом, длинный опрос значительно уменьшает количество ненужных HTTP-запросов и по сравнению с этим экономит ресурсы.
  • Недостаток: зависание соединения также может привести к пустой трате ресурсов.

режим длинного потока соединения (потока) на основе iframe

Когда мы встраиваем iframe в страницу и устанавливаем его src, сервер может «непрерывно» выводить контент клиенту через длинное соединение. Например, мы можем вернуть сегмент клиентуscriptэтикетка завернутаjavascriptcode, код будет выполняться в iframe. Поэтому, если мы предварительноiframeФункция-обработчик process() определена на родительской странице , и каждый раз, когда необходимо отправить новые данные, она записывается в ответе соединения. Затем этот код в iframe вызовет предопределенную функцию process() на родительской странице. (Это немного похоже на то, как JSONP передает данные?)

  // 在父页面中定义的数据处理方法
  function process(data) {
      // do something
  }

  // 创建不可见的iframe
  var iframe = document.createElement('iframe');
  iframe.style = 'display: none';
  // src指向后端接口
  iframe.src = '/long_iframe';
  document.body.appendChild(iframe);

Бэкэнд по-прежнему использует узел в качестве примера

const app = http.createServer((req, res) => {
    // 返回数据的方法,将数据拼装成script脚本返回给iframe
    const iframeSend = data => {
        let script = `<script type="text/javascript">
                        parent.process(${JSON.stringify(data)})
                    </script>`;
        res.write(script);
    };

    res.setHeader('connection', 'keep-alive');
    // 注意设置相应头的content-type
    res.setHeader('content-type', 'text/html; charset=utf-8');        
    // 当有数据更新时,服务端“推送”数据给客户端
    EVENT.addListener(MSG_POST, iframeSend);

    req.socket.on('close', () => {
        console.log('iframe socket close');
        // 注意在连接关闭时移除监听,避免内存泄露
        EVENT.removeListener(MSG_POST, iframeSend);
    });
});

Эффект следующий:

webSocket

Однако в использовании iframe есть небольшой недостаток, поэтому этот iframe эквивалентен тому, что он никогда не загружается, поэтому в браузере всегда будет флаг загрузки.

Его плюсы и минусы такие же, как и у длинного опроса выше.

Websocket

Некоторые функции и основные принципы использования WebSocket не будут здесь повторяться, см. другой блог.Веб-сокет (1) Анализ; Примерный код выглядит следующим образом:Сервер

    const express = require('express');
    const app = express();
    const server = require('http').Server(app);
    const WebSocket = require('ws');

    const wss = new WebSocket.Server({port: 8080});
    wss.on('connection', function connection(ws) {
        console.log('server: receive connection');
        ws.on('message', function incoming(message) {
            console.log('server: recevied: %s', message);
        });
        ws.send('world');
    });

    app.get('/', function (req, res) {
        res.sendfile(__dirname + '/index.html');
    });
    app.listen(3000);

клиент

    const ws = new WebSocket('ws://localhost:8080');
    ws.onopen = function () {
        console.log('ws onopen');
        ws.send('from client:hello');
    };
    ws.onmessage = function (e) {
        console.log('ws onmessage');
        console.log('from server:' + e.data);
    }

Эффект операции следующий:

webSocket

  • Преимущества: нет потери производительности
  • Недостаток: изучение нового набора библиотек запросов

SSE (Server-Sent Events)

Server-SentдаHTML5Придумайте стандарт. Создается между клиентом и серверомTCPподключиться, тои поддерживать эту связь, пока клиент или сервер не отключится,ServerSentИспользуется механизм «спросить» + «ответить».После установления соединения браузер будет периодически отправлять сообщение на сервер, чтобы спросить, есть ли у него собственное сообщение. Принцип его реализации аналогичен тому, что мы упоминали в предыдущем разделе.режим длинного соединения на основе iframe. Содержимое ответа HTTP имеет специальныйcontent-type —— text/event-stream, заголовок ответа идентифицирует содержимое ответа какпоток событий, клиентне закроет соединение, но подождите, пока сервер будет непрерывно отправлять результаты ответа. Спецификация SSE относительно проста и в основном делится на две части: объект EventSource в браузере и соединение между серверной и браузерной сторонами.Протокол.

Основное использование

Этот объект может быть создан в браузере через конструктор Vectorource

  var source = new EventSource('/sse');

а такжеSSEСодержимое ответа можно рассматривать какпоток событий, состоящий из разных событий. Эти события запускают внешний интерфейсEventSourceметоды на объектах.

  // 默认的事件
  source.addEventListener('message', function (e) {
      console.log(e.data);
  }, false);

  // 用户自定义的事件名
  source.addEventListener('my_msg', function (e) {
      process(e.data);
  }, false);

  // 监听连接打开
  source.addEventListener('open', function (e) {
      console.log('open sse');
  }, false);

  // 监听错误
  source.addEventListener('error', function (e) {
      console.log('error');
  });

EventSource работает, прослушивая события. Обратите внимание, что приведенный выше код прослушивает событие y_msg, SSE поддерживает пользовательские события, а событие по умолчанию получает данные, прослушивая сообщение. Код реализации выглядит следующим образом:

клиент

  // 显示聊天信息
  let chat = new EventSource("/chat-room");
  chat.onmessage = function (event) {
      let msg = event.data;
      $(".list-group").append("<li class='list-group-item'>" + msg + "</li>");
      // chat.close(); 关闭server-sent event
  };

  // 自定义事件
  chat.addEventListener("myChatEvent", function (event) {
      let msg = event.data;
      $(".list-group").append("<li class='list-group-item'>" + msg + "</li>");
  });

серверные ноды

  var express = require('express');
  var router = express.Router();
  router.get('/chat-room', function (req, res, next) {
      // 当res.white的数据data 以\n\n结束时 就默认该次消息发送完成,触发onmessage方法,以\r\n不会触发onmessage方法
      res.header({
          "Content-Type": "text/event-stream",
          "Cache-Control": "no-cache",
          "Connection": "keep-alive"
      });

      // res.white("event: myChatEvent\r\n"); 自定义事件
      res.write("retry: 10000\r\n"); // 指定通信的最大间隔时间
      res.write("data: start~~\n\n");
      res.end(); // 不加end不会认为本次数据传输结束 会导致不会有下一次请求
  });
  • Преимущества: клиенту нужно подключиться только один раз, и сервер будет регулярно нажимать его, если только один конец не отключится. И SSE автоматически переподключится, когда соединение неожиданно прервется.
  • Недостаток: чтобы выучить новую грамматику

Суммировать

Сравнение вышеупомянутых четырех технологий обмена мгновенными сообщениями в Интернете можно рассматривать с разных точек зрения, и их приоритеты различны.В основном их можно разделить на две категории на основеhttpа такжеtcpОдин из двух видов общения.

Вопросы совместимости: короткий опрос > длинный опрос > длинное соединение SSE > WebSocket

Учитывайте производительность: WebSocket > Длинное соединение SSE > Длинный опрос > Короткий опрос

Пуш сервера: WebSocket> Длинное соединение SSE> Длинный опрос

Ссылаться на

Различные принципы и примеры технологии "Server Push" (опрос/COMET/SSE/WebSocket)

WebSocket технологии push-сервера JavaScript

Опрос, длинный опрос, долгое соединение, веб-сокет

Механизм push-сообщений — опрос, длинный опрос, SSE (событие, отправленное сервером) и WS (WebSocket)