Введение в SingalR¶
Любой разработчик разработчик веб-приложений, мобильных приложений или приложений для “интернета вещей” (internet of things, IoT) однажды приходит к пониманию, что стандартной модели коммуникации с сервером — запрос-ответ — недостаточно. В некоторых случаях необходимо получать от сервера обновления, инициированные событием на сервере, а не запросом от клиента.
Иногда для решения подобной задачи можно просто снова и снова опрашивать сервер. Однако это выглядит расточительным, особенно, если клиент использует лимитированное соединение — бесконечные запросы могут очень быстро выбрать весь лимит.
Альтернативой этому будет использование протокола WebSocket, предназначенного для двунаправленной коммуникации между клиентом и сервером. Однако “из коробки” Websocket использует поток бинарных данных вместо человекочитаемых абстракций, поэтому для использования Websocket нужно написать примерно такой код:
private static async Task ReceiveAsync(ClientWebSocket ws)
{
var buffer = new byte[4096];
while (true)
{
var result = await ws.ReceiveAsync(
new ArraySegment<byte>(buffer),
CancellationToken.None);
if(result.MessageType == WebSocketMessageType.Close)
{
await ws.CloseOutputAsync(
WebSocketCloseStatus.NormalClosure,
string.Empty,
CancellationToken.None);
break;
}
else
{
Console.WriteLine(Encoding.Default.GetString(Decode(buffer)));
buffer = new byte[4096];
}
}
}
private static byte[] Decode(byte[] packet)
{
var i = packet.Length - 1;
while (i >= 0 && packet[i] ==0)
{
--i;
}
var temp = new byte[i + 1];
Array.Copy(packet, temp, i + 1);
return temp;
}
Как видно, код не особо интуитивный и лёгкий для понимания.
Но для .NET разработчиков всё это не нужно — у них есть замечательная библиотека SignalR.
Почему SignalR такой замечательный¶
SignalR позволяет реализовать двухстороннюю коммуникацию в реальном времени в виде простых методов. Например, серверный код отправки сообщения будет выглядеть так:
А вот клиентский код, который вызовет этот метод:
var message = $('#broadcast').val();
connection.invoke("BroadcastMessage", message)
.catch(err => console.error(err.toString()));
“Под капотом” SignalR использует протокол WebSocket, однако не только его. Вот возможные протоколы, в порядке приоритета:
- Websocket — предпочтительный протокол;
- Server-sent events — в случае, если websocket недоступен;
- Long polling — в случае, если недоступны предыдущие два.
Если необходимо, можно указать, какой протокол использовать. Однако ваш код будет абсолютно независим от используемого протокола.
Для чего можно использовать SignalR¶
SignalR может быть использован в любых сценариях, когда требуется получать обновления от сервера в реальном времени, либо когда требуется высокая частота (скорость?) обмена данными между клиентом и сервером. Согласно документации вот некоторые примеры, для которых SignalR будет наилучшим выбором:
- Высокочастотный обмен данными — игры, голосования, аукционы;
- Мониторинг и графики — панели управления, информация с финансовых рынков, мгновенные обновления торгов, таблица лидеров многопользовательской игры, мониторинг “интернета вещей”;
- Чат — комнаты чатов, чат-боты, поддержка клиентов, мессенджер, внутриигровой чат и т.п.;
- Обновление положения на карте — трекинг логистики, доставки, обновления статуса транспортировки, приложения с геопозиционированием;
- реклама, таргетируемая в реальном времени — персонализированные предложения и реклама, интерактивная реклама;
- приложения для совместной работы — приложения для соавторства, приложения — вайтборды, приложения для совещаний;
- пуш-уведомления — соцсети, игры, почта, предупреждения для путешественников;
- вещание в реальном времени — “прямые эфиры” в аудио и видео формате, новостное вещание;
- интернет вещей — метрики подключённых устройств, дистанционное управление, статус в реальном времени и поиск местонахождения;
- автоматизация — срабатывание при входящих событиях.
Дата создания : 11 декабря 2022 г.