ASP.NET MVC - WebSocket Strategy
Веб-сокеты позволяют организовать двунаправленное общение между клиентом и сервером, а так же позволяют устанавливать новое соединение не при каждом запросе, а единожды на сессию.
Как делали раньше
HTTP Polling
После каждого ответа отправляем новый AJAX-запрос, тем самым создаем иллюзию непрекращающегося соединения. Очень расточительный метод.
HTTP Long polling
Клиент делает AJAX-запрос к серверу, а сервер держит его до тех пор, пока у него не появятся данные для отсылки клиенту. То есть соединение устанавливается как бы заранее.
Как сейчас
Веб-сокеты выступают как замена HTTP в качестве протокола взаимообщения. Не стоит его использовать в качестве основного средства коммуникации, а только для двунаправленных и продолжительных взаимодействий.
Соединение через веб-сокеты включает клиентскую и серверную часть. Состоит из 3 шагов:
- Установление соединения путем хэндшейка
 - Запрос, чтобы убедиться, что сервер начал ждать взаимодействия
 - Передача данных
 
Когда запрашивается веб-сокет, браузер сначала открывает простое HTTP-соединение с сервером. Затем браузер шлет запрос на апгрейд соединения до веб-сокетного. Если запрос прошел и хэндшейк удался, то дальнейшее общение происходит в рамках одного TCP-сокета.
var socket;   
$(document).ready(function () {   
	socket = new WebSocket("ws://localhost:1046/socket/handle");  
	socket.addEventListener("open", function (evnt) {  
		$("#display").append('connection');
		}, 
	false);   
	socket.addEventListener("message", function (evnt) {  
		$("#display ").append(evnt.data);
	}, false);   
	socket.addEventListener("error", function (evnt) {  
		$("#display ").append('unexpected error.');
	}, false);   
...   
});Когда внедряем в приложение поддержку веб-сокетов, нужно определять, как будем управлять соединением. Обычно это делается в HTTP-хэндлере или модуле. Нужно реализовать процесс апгрейда соединения при соответствующем запросе. Это делается так:
HttpContext.Current.AcceptWebSocketRequest(Func<AspNetWebSocketContext,  
Task>)Передаваемый делегат будет вызван после хэндшейка. Пример:
public async Task MyWebSocket(AspNetWebSocketContext context)   
{   
	while (true)   
	{   
		ArraySegment<byte> arraySegment = new ArraySegment<byte>(new byte[1024]);   
		// open the result. This is waiting asynchronously  
		WebSocketReceiveResult socketResult =   
		await context.WebSocket.ReceiveAsync(arraySegment,   
			CancellationToken.None);   
  
		// return the message to the client if the socket is still open  
		if (context.WebSocket.State == WebSocketState.Open)   
		{   
			string message = Encoding.UTF8.GetString(arraySegment.Array, 0,   
				socketResult.Count);   
			userMessage = "Your message: " \+ message + " at " +   
			DateTime.Now.ToString();  
			arraySegment = new   
				ArraySegment<byte>(Encoding.UTF8.GetBytes(message));   
  
			// Asynchronously send a message to the client   
			await context.WebSocket.SendAsync(arraySegment,   
				WebSocketMessageType.Text,   
				true, CancellationToken.None);   
		}   
		else { break; }   
	}   
}Connection loss strategy
Нужно предусмотреть план действий при потере соединения. Действия эти будут производиться на клиенте. Когда соединение закроется, у клиента вызовется либо onclose либо onerror. В этом случае нужно переоткрывать соединение и слать запрос еще раз.
Приложение должно слать запрос и ждать ответа, а затем на основании ответа или его отсутствия, решать, приняла ли другая сторона запрос. Если нет - слать еще раз. Однако возможно и такое, что принимающая сторона получила запрос, но не смогла ответить. Нужно быть готовым к нескольким одинаковым запросам.
Когда использовать
Зачастую используют в мессенджерах и дэшбордах. Следует помнить, что у веб-сокетных запросов нет HTTP-заголовков, хоть они и ведут себя как HTTP-запросы.