Как подружить SignalR 2 и ASP.NET 5 в ожидании выхода SignalR 3?

В последнее время мне часто напоминают, что проект в галерее MSDN не обновляется вот уже достаточно продолжительное время, причину такой затянувшейся паузы и о том, что будет дальше с обновлением я опишу в данной статье. Давайте посмотрим на график выпуска релизов ASP.NET 5 приведённый на официальном сайте на GitHub. Для удобства привожу его ниже, взяв из 13-ой ревизии документа на момент написания статьи, также добавлена дата релиза ASP.NET Beta5.

Релиз – Дата: Beta5 – 30.06.2015 => Beta6 – 27.07.2015 => Beta7 – 02.09.2015

Релиз – Дата: Beta8 – 15.10.2015 => RC1 – 18.11.2015 => RC2 – 02.2016 => RTM – первый квартал 2016

Из вышеприведённого графика видно, что релизы выходили достаточно часто ну и критических обновлений тоже было много. Последняя версия SignalR 3 – Beta5 уже не работает с версией ASP.NET 5 Beta7, не говоря уже о текущей RC1. И наконец в конце официального расписания релизов сказано, что поддержка Visual Basic, SignalR 3, Web Pages 4 в ASP.NET 5 появится после выхода RTM, где-то в третьем квартале 2016. Отсюда уже ясно, что, обновив пример из галереи до ASP.NET 5 RC 1, он перестанет работать. Так ка же быть? Временно использовать SignalR 2. Приложение «Real-Time Data Editing» в последний раз было обновлено используя Visual Studio 2015 RTM и ASP.NET Beta5. Я сделал так, чтобы в решении Visual Studio сохранялись предыдущие версии приложения:

их можно скачивать и запускать также (детальное описание о том, как это сделать приведено на странице приложения). Для начала скачаем и обновим приложение из архива RealTimeDataEditorVS2015RTM-ASP5BETA5. Процесс обновления не буду приводить дабы не загромождать статью, да и сложного в этом ничего нет. После обновления имеем следующее:

приложение компилируется и запускается, но не показывает данные, так как нет SignalR 3. А что если подключить текущую dev-ветку кода SignalR 3 в проект? Приложение скомпилируется без ошибок, но вот работать не будет, как показано ниже.

Ну что же, в будущем исправят, ну а пока продолжим установку SignalR 2 в проект. Нужно добавить в проект перечисленные ниже сборки:

"Microsoft.AspNet.Owin": "1.0.0-rc1-final"
"Microsoft.AspNet.SignalR.Core": "2.2.0"
"Microsoft.AspNet.SignalR.Owin": "1.2.2"
Также нужно учесть, что последние две сборки не совместимы с .NET Core и придётся использовать полноценный .NET Framework.

Далее нужно освежить знания о конвейере ASP.NET и вспомнить про модули OWIN. В добавок нужно изучить все те изменения, которые были сделаны при реализации OWIN в ASP.NET 5. На основе этих знаний получаем один единственный тип:

 namespace RealTimeDataEditor
{
    using AppFunc = Func<IDictionary<string, object>, Task>;

    public static class BuilderExtensions
    {
        public static IApplicationBuilder UseAppBuilder(
            this IApplicationBuilder app, 
            Action<IAppBuilder> configure)
        {
            app.UseOwin(addToPipeline =>
            {
                addToPipeline(next =>
                {
                    var appBuilder = new AppBuilder();
                    appBuilder.Properties["builder.DefaultApp"] = next;

                    configure(appBuilder);

                    return appBuilder.Build<AppFunc>();
                });
            });

            return app;
        }

        public static void UseSignalR2(this IApplicationBuilder app)
        {
            app.UseAppBuilder(appBuilder => appBuilder.MapSignalR());
        }
    }
}

 

Используем старый модуль SignalR 2 в новой версии,

 public void Configure(IApplicationBuilder app, IHostingEnvironment env,
    ILoggerFactory loggerFactory)
{
    app.UseStaticFiles();
    app.UseSignalR2();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
} 

и видим, что всё работает нормально.

Всё хорошо, но вот только в данном случае SignalR 2 не будет использовать веб-сокеты, они не доступны.