javascript — Длинный опрос или полнодуплексное соединение? Где подвох?

Я внедряю систему обмена сообщениями с долгим опросом, чтобы иметь обновления в реальном времени для моих пользователей.
При этом я заметил, что некоторые веб-сайты, такие как Hotmail, также используют запросы xhr, но они, похоже, немного отличаются от того, который я реализовал.

Как вы можете видеть на картинке, в моей реализации клиент делает запрос, а сервер удерживает его до тех пор, пока не появятся новые обновления данных. Затем отправляет обратно полезную нагрузку и закрывает соединение. После получения javascript отправляет новый запрос на веб-сервер.

Вместо этого Hotmail отправляет запрос обратно, оставляя соединение открытым. Как это возможно?? И как я могу реализовать это сам? И самое главное, какая разница?

Спасибо.

Долгосрочный опрос

2

Решение

Hotmail использует веб-сокеты. Запросы веб-сокетов отличаются от запросов http тем, что соединение с веб-сокетами постоянно, когда пользователь находится на веб-сайте. Итак, общение в кратчайшие сроки происходит следующим образом: когда пользователь впервые открывает ваш сайт, он отправляет http-запрос на ваш сервер. Так как протокол http находится на 7-м уровне Модель OSI, запрос проходит через уровень TCP и устанавливает сокет-соединение (которое находится на 5-м уровне модели OSI) с сервером. Используя соответствующую технологию веб-сокетов на стороне сервера, сервер может использовать это постоянное сокетное соединение с клиентом для передачи данных, когда это необходимо.

В зависимости от того, какой язык вы используете для своей серверной части, вы можете использовать несколько различных технологий / библиотек для реализации веб-сокетов. Для веб-приложения asp.net вы можете использовать Microsoft’s SignalR. Если вы используете javscript (Node.js) для своего сервера, чем вы можете использовать Socket.io. Обратите внимание, что вы также можете использовать Socket.io, даже если вы не используете node.js для своей серверной части, но реализации не будут такими уж тривиальными, потому что теперь у вас будет 2 разных сервера, которые потенциально могут понадобиться для обмена данными (например, : сеансы или база данных).

Хорошая вещь о Node.js и SignalR состоит в том, что они очень производительны и очень масштабируемы для многих пользователей, особенно Node.js. Еще одна замечательная особенность обеих этих технологий заключается в том, что если браузер клиента не поддерживает веб-сокеты, у него есть соответствующие резервные методы, такие как отправленные события сервера, опрос Ajax, длинный опрос Ajax, скрытый элемент iframe …

Для дальнейшего чтения я рекомендую это Stackoverflow вопрос

1

Другие решения

Существует два наиболее распространенных двунаправленных механизма HTTP, см. RFC6202 «Известные проблемы и лучшие практики использования длинного опроса и потоковой передачи в двунаправленном HTTP»:

  • Длинный опрос HTTP: сервер пытается «держать открытым» (не
    немедленно отвечать на каждый HTTP-запрос, отвечая только тогда, когда
    Есть события для доставки. Таким образом, всегда есть
    ожидающий запрос, на который сервер может ответить с целью
    доставки событий по мере их возникновения, тем самым сводя к минимуму задержки в
    доставка сообщений.

  • HTTP Streaming: сервер держит запрос открытым бесконечно; тот
    никогда не завершает запрос и не закрывает соединение, даже
    после того, как он передает данные клиенту.

Вы также можете найти подробный список проблем этих подходов в RFC6202. Каждый из этих методов имеет свои преимущества и недостатки.

Итак, во время потоковой передачи HTTP соединение не прерывается:

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

  1. Клиент делает начальный запрос и затем ждет
    ответ.

  2. Сервер откладывает ответ на запрос опроса до обновления
    доступно, или пока определенный статус или тайм-аут не имеет
    произошло.

  3. Когда доступно обновление, сервер отправляет его обратно
    клиент как часть ответа.

  4. Данные, отправленные сервером, не завершают запрос или
    подключение. Сервер вернется к шагу 3.

1

Я думаю, что есть лучший подход, чем использование длинных опросов. Вы можете реализовать соединения WebSocket. Тогда у вас будет постоянное двунаправленное соединение с сервером. WebSocket — это протокол обновления, основанный на HTTP, который был создан для того, чтобы избежать таких «обходных» приемов, как длительный опрос.
Если вы хотите прочитать об этом более подробно:

https://tools.ietf.org/html/rfc6455

http://www.html5rocks.com/en/tutorials/websockets/basics/

Если вы хотите поддерживать старые браузеры, которые не могут устанавливать WebSockets, вы можете использовать что-то вроде Dojox / Socket, которое автоматически использует долгий опрос в качестве запасного варианта.

http://dojotoolkit.org/api/1.10/dojox/socket.html

https://www.sitepen.com/blog/2012/11/05/dojo-websocket-with-amd/

1