[Из песочницы] Вышла первая версия SignalR для ASP.Net Core 2.0

habr.png

Привет, Хабр!
14 сентября было объявлено о выпуске первой версии SignalR для ASP.Net Core, в связи с чем я решился перевести заметку, посвященную даному событию, немного её дополнив. Оригинал заметки доступен в блоге на MSDN.


Что нового?

SignalR для ASP.Net Core является переписанной с нуля версией оригинального SignalR. Новый SignalR проще, более надёжен и легче в применении. Несмотря на эти внутренние изменения, мы старались сделать API библиотеки наиболее близким к предыдущим версиям.


JavaScript/TypeScript клиент

SignalR для ASP.Net Core имеет совершенно новый JavaScript клиент. Он написан с использованием TypeScript и более не зависит от JQuery. Клиент также может использоваться из Node.js с несколькими дополнительными зависимостями.


Клиент распространяется в качестве npm модуля, который содержит Node.js версию клиента (подключается через require), и также версию для браузера, которую можно встроить используя тег


Подключение скрипта позволит начать соединение с сервером и обмениваться с ним командами


let connection = new signalR.HubConnection('/chat');

connection.on('send', data => {
    console.log(data);
});

connection.start()
            .then(() => connection.invoke('send', 'Hello'));


Для использования управляемого клиента необходимо добавить ссылку на пакет Microsoft.AspNetCore.SignalR.Client




    
    Exe
    netcoreapp2.0
    

    
    
    


после чего можно будет обращаться к методам хаба и обрабатывать вызовы методов клиента.


Если вы хотите воспользоваться преимуществами потоковой передачи, вам необходимо создать метод хаба который будет возвращать ReadableChannel или IObservable. Далее приведён метода хаба из примера StockTimer, который передаёт в потоке стоимости акций


public IObservable StreamStocks()
{
    return _stockTicker.StreamStocks();
}


JavaScript код вызываемый данным методом выглядит так


function startStreaming() {
    connection.stream("StreamStocks").subscribe({
        next: displayStocks,
        error: function (err) {
            logger.log(err);
        }
    });
}


Каждый раз, когда сервер отправляет элемент потока, будет вызван клиентский метод displayStocks
Вызов метода хаба из кода C# приведён далее


private async Task StartStreaming()
{
    var channel = connection.Stream("StreamStocks", CancellationToken.None);
    while (await channel.WaitToReadAsync())
    {
        while (channel.TryRead(out var stock))
        {
            Console.WriteLine($"{stock.Symbol} {stock.Price}");
        }
    }
}


Переход с существующей версии SignalR

В течении ближайших недель будет выпущена документация по миграции с предыдущей версии SignalR.


Известные проблемы

  • Соединение через транспорт SSE может быть утеряно спустя две минуты неактивности в случае когда сервер запущен через IIS
  • Веб-сокеты не работают в случае использования сервера IIS на ОС Windows 7 или Windows Server 2008 R2
  • Использование SSE в клиенте на C# может привести к зависанию клиента в случае его закрытия в период получения данных с сервера
  • Потоковые вызовы не могут быть отменены клиентом
  • Сборка продакшн версии не возможна с помощью angular-cli, так как UglifyJS не поддерживает стандарт ES6. Временное решение для данной проблемы представлено в этом комментарии


От автора перевода

От себя хочу добавить небольшой пример использования TypeScript версии клиента в SPA приложении на Angular. После выполнения всех действий приведённых выше в разделе «Начало работы», в Angular-компоненте достаточно импортировать класс HubConnection и воспользоваться его методами. В базовом примере приложения созданного с помощью команды dotnet new angular, в компонент fetchdata.component.ts я добавил функционал отображения количества кликов с компонента counter следующим образом


import { Component, Inject } from '@angular/core';
import { Http } from '@angular/http';
import { HubConnection } from "@aspnet/signalr-client";

@Component({
    selector: 'fetchdata',
    templateUrl: './fetchdata.component.html'
})
export class FetchDataComponent {
    public forecasts: WeatherForecast[];
    public count: number;
    private notificationHub: HubConnection;

    constructor(http: Http, @Inject('BASE_URL') baseUrl: string) {
        http.get(baseUrl + 'api/SampleData/WeatherForecasts').subscribe(result => {
            this.forecasts = result.json() as WeatherForecast[];
        }, error => console.error(error));

        this.notificationHub = new HubConnection("/notifications");
        this.notificationHub.on("send", (data) => {
            this.count = data;           
        });
        this.notificationHub.start();
    }
}


Адреса хаба указанный в вызове конструктора должен совпадать с тем, который указан в классе Startup приложения ASP.Net Core (в примере из перевода таким адресом является «chat»). Метод Send хаба вызывается из компонента counter следующим образом


this.notificationHub.invoke("send", this.currentCount);


P.S. Это мой первый пост и одновременно перевод, по этому прошу замечания к его качеству отправлять мне в ЛС.

© Habrahabr.ru