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

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

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

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

Спасибо.

Длинный опрос


person franks    schedule 10.10.2015    source источник


Ответы (3)


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

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

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

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

person Dejan Bogatinovski    schedule 10.10.2015
comment
Я выбрал это, потому что это в основном отвечает на мои вопросы. Я реализую систему обмена сообщениями в чате. Пока долгий опрос работает просто прекрасно. Но это заставило меня на самом деле придумать лучшую идею. Ввод в режиме реального времени, который покажет пользователю, печатает ли другой человек. Поэтому я предполагаю, что веб-сокет будет лучшим решением. Я прав? - person franks; 11.10.2015
comment
Да, веб-сокеты - лучшее решение для вашего случая. Фактически, в прошлом году я реализовал веб-приложение, похожее на скайп, для одного из моих университетских проектов. По сути, это веб-сайт php/mysql для всех основных функций, таких как рендеринг веб-сайта и доступ к базе данных, но я также реализовал сервер node.js, который использует socket.io для обновлений в реальном времени. По сути, у меня есть чат с функциями обмена сообщениями и набора текста в реальном времени, но я также пошел дальше и реализовал WebRTC, чтобы было одноранговое аудио/видео общение. Я могу загрузить этот проект в github, если хотите. - person Dejan Bogatinovski; 12.10.2015
comment
Это потрясающе! Спасибо. На данный момент я бы предпочел придерживаться живого чата в стиле facebook, потому что это добавит слишком много накладных расходов моему проекту ... хотя смайлики могут помочь. - person franks; 12.10.2015

Существует два наиболее распространенных двунаправленных механизма HTTP, см. RFC6202 "Известные проблемы и рекомендации по использованию длинных опросов". и потоковая передача в двунаправленном HTTP":

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

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

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

Итак, во время стриминга HTTP соединение не разрывается:

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

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

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

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

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

person Orest Hera    schedule 10.10.2015

Я думаю, что, возможно, есть лучший подход, чем использование длительного опроса. Вы можете реализовать соединения 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/

person Paul Fröhling    schedule 10.10.2015