Статьи

Методы взаимодействия клиента с сервером в Интернете


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

Сегодня пользователи ожидают, что в их проектах, извините, за «опыт», доступна форма «реального времени». Такие вопросы, как «Я хочу, чтобы этот тикер обновлялся при каждом изменении цены» или «Я хочу просматривать GPS-местоположения моих транспортных средств в режиме реального времени на этой карте». Или даже лучше: для совместной работы людей часто требуются живые уведомления и изменения в браузере, так что всякий раз, когда пользователь запускает задачу или событие, другие пользователи, сотрудничающие немедленно, получают уведомление. Подумайте о таблицах Google, где вы можете работать вместе. Подумайте, чат в Facebook. Подумайте в Твиттере, где автоматически появляются новые сообщения. Подумайте о своих приложениях, посыпав соусом в реальном времени.

Как бы вы это реализовали?

SignalR websockets html5 длинный опрос

Но что, если сервер хочет общаться с клиентом?

На протяжении многих лет веб-разработчики очень изобретательно работали над характером запросов / ответов в Интернете. На разных платформах используются два метода, которые обеспечивают относительно легкий обход проблемы «парадигмы HTTP», когда клиент инициирует любое соединение: простой опрос с использованием Ajax и один из вариантов — длинный опрос.

Простой Ajax-опрос, ну, в общем-то, прост: клиент «опрашивает» сервер с помощью Ajax-запроса, на который сервер отвечает, если есть данные. Клиент ждет некоторое время и снова проходит этот процесс. Схематически это будет следующим:

образ

Проблема в том, что сервер все еще зависит от клиента, инициирующего соединение. Всякий раз, когда в течение интервала опроса сервер имеет данные для клиента, эти данные могут быть отправлены клиенту только при следующем цикле опроса. Это, вероятно, не проблема, когда интервал опроса находится в диапазоне 100 мс, за исключением того факта, что вы будете молотить ваши серверы при этом. С того момента, как ваш интервал опроса увеличивается до 2 или даже 30 секунд, вы теряете часть идеи общения в режиме реального времени.

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

образ

Интервал опроса отсутствует: до тех пор, пока соединение открыто, сервер может отправлять данные обратно клиенту. Круто, верно? Не совсем … Ваши серверы не будут забиты миллиардами запросов, но для обработки запросов потребуется некоторое время («длинный опрос»). Представьте себе, что будет делать ваш пул потоков ASP.NET в таком случае … Ну, если вы не реализуете свою сторону сервера, используя IAsyncHttpHandler или подобное. В противном случае ваши серверы просто перестанут принимать запросы.

HTML5 на помощь?

Как мы уже видели, обе существующие технологии работают для симуляции полнодуплексной связи между клиентом и сервером. Однако у них обоих есть некоторые недостатки, если вы не знаете, что делаете. Кроме того, методы, описанные ранее, просто имитируют двунаправленную связь. Разве не было бы неплохо иметь решение, которое прекрасно работает и предназначено для этого? Встречайте HTML5 WebSockets .

WebSockets предлагает реальное двунаправленное TCP-соединение между клиентом и сервером. Это верно, TCP (не HTTP) соединение. Чтобы установить соединение WebSocket, клиент отправляет запрос рукопожатия WebSocket по HTTP, сервер отправляет ответ рукопожатия WebSocket с подробной информацией о том, как открыть фактическое соединение TCP. Так просто! Схематично:

образ

К сожалению, сеть развивается не так быстро … WebSockets все еще является черновой спецификацией («CTP» или «альфа», как вы будете). Не все браузеры поддерживают их. А поскольку они используют необработанное TCP-соединение, многие прокси-серверы, используемые в компаниях, пока не поддерживают их. Мы доберемся туда, только не сегодня. Кроме того, если вы хотите использовать WebSockets с ASP.NET, вам придется использовать предварительную версию .NET 4.5.

Так что же делать в этом запутанном мире? Как достичь двунаправленной связи в реальном времени через Интернет сегодня?

СигналР на помощь!

SignalR — это «библиотека асинхронной сигнализации для ASP.NET, над которой работает Microsoft для создания многопользовательских веб-приложений в реальном времени». Позвольте мне перефразировать это: SignalR — это библиотека ASP.NET, которая использует три метода, которые я описал ранее, для создания единого взаимодействия между клиентом и сервером.

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

var helloConnection = $.connection.hello; 

helloConnection.sayHelloToMe = function (message) { 
	alert(message); 
}; 

$.connection.hub.start(function() { 
	helloConnection.sayHelloToAll("Hello all!"); 
});

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

   
public class Hello : Hub { 
	public void SayHelloToAll(string message) { 
		Clients.sayHelloToMe(message); 
	} 
}

Вы уже видите ссылку? Клиент JavaScript вызывает метод C # «SayHelloToAll», как если бы это была функция JavaScript. Сторона C # вызывает всех своих клиентов (имеется в виду 200 000 окон браузера, подключающихся к этой службе :-)) Метод JavaScript «sayHelloToMe», как если бы это был метод C #.

Если добавить, что поддерживаются не только клиенты JavaScript, но также Windows Phone, Silverlight и обычный .NET, это звучит интересно? Если я добавлю, что SignalR может использовать любой из трех методов, описанных ранее в этом посте, в зависимости от того, что клиент и сервер поддерживают, даже не заботясь о вас… это звучит интересно? Если ответ «да», следите за обновлениями для некоторых последующих сообщений …

 

Источник: http://blog.maartenballiauw.be/post/2011/11/29/Techniques-for-real-time-client-server-communication.aspx