Добавьте собственный сервер SignalR в. Net Core Worker Service - PullRequest
0 голосов
/ 26 февраля 2020

Я пытаюсь расширить . NET Core Worker Service (<Project Sdk="Microsoft.NET.Sdk.Worker">) с помощью SignalR (веб-приложение с собственным размещением).
Все примеры / Обучающие программы / документы, которые я нашел, основаны на веб-приложениях, поэтому они не соответствуют моему случаю.

Это то, что я делал до сих пор:
MyService Program.cs:

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>                       

            Host.CreateDefaultBuilder(args)
                .UseWindowsService()            
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<Worker>();
                    DependencyBuilder.Build(hostContext, services);  // inject the stuff I need in my service

                    // create a SignalR Web host               
                    SignalRWebHostCreator.CreateHost(services, "http://localhost:8090", (endpoints) => {
                        endpoints.MapHub<MyHub>("/result");
                    });
                });
    }

и класс, который я хочу использовать, чтобы "расширить" серв ie с помощью серверное приложение SignalR.


public class SignalRWebHostCreator
    {
        public static void CreateHost(IServiceCollection services, string serviceUrl, Action<IEndpointRouteBuilder> mapHubs)
        {
            services.AddSignalR();  // is it ok here ?

            WebHost.CreateDefaultBuilder()
                .UseUrls(serviceUrl)
                .Configure((IApplicationBuilder app) => {
                    app.UseRouting();

                    app.Map("/check", config => {  // just a test: it works!
                        config.Run(async context =>
                        {   
                            context.Response.ContentType = "text/plain";
                            byte[] data = System.Text.Encoding.UTF8.GetBytes("OK");
                            await context.Response.Body.WriteAsync(data, 0, data.Length);
                            await context.Response.Body.FlushAsync();
                        });
                    });

                    app.UseEndpoints(endpoints =>
                    {
                        //endpoints.MapHub<ClockHub>("/hubs/clock");   // ERROR
                        //endpoints.MapHub<PingHub>("/ping");  // ERROR
                        //mapHubs(endpoints);    // ERROR
                    });
            })
            .Build().Run();
        }
    }

(ClockHub взят из примера MS, а PingHub - еще один простой концентратор, который я пытался использовать вместо своих «внедренных» концентраторов)

Он правильно запускает веб-приложение и правильно реагирует на URL http://localhost: 8090 / чек .

Когда я раскомментирую звонки на enpoint.MapHub() или мои обычные действия, у меня появляется эта ошибка:

System.InvalidOperationException : 'Невозможно найти требуемые службы , Добавьте все необходимые службы, вызвав IServiceCollection.AddSignalR внутри вызова ConfigureServices (...) в коде запуска приложения.

2-я попытка:
Похоже на service.AddSignalR() не выполняет свою работу, поэтому я добавил это в SignalRWebHostCreator :

.Configure((IApplicationBuilder app) => {
      app.ApplicationServices = services.BuildServiceProvider();

и теперь у меня появляется эта ошибка:
System.InvalidOperationException : 'Невозможно разрешить службу для типа' System.Diagnostics.DiagnosticListener 'при попытке активировать' Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware '.'

, которая хотя бы имеет стек вызовов:
_Это исключение было изначально сгенерировано в этом стеке вызовов:
Microsoft.Extensions.Internal.ActivatorUtilities.ConstructorMatcher.CreateInstance (System.IServiceProvider)
Microsoft.Extensions.Internal.ActivatorUtilities.CreateInstance (System.IServiceProvider System, , объект [])
Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.UseMiddleware.AnonymousMethod__0 (Microsoft .AspNetCore.Http.RequestDelegate)
Microsoft.AspNetCore.Builder.ApplicationBuilder.Build ()
Microsoft.AspNetCore.Hosting.WebHost.BuildApplication ()
Microsoft.AspNetCore.Hosting.WebHost.St (System.Threading.CancellationToken)
System.Runtime.ExceptionServices.ExceptionDispatchInfo. .TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult () _

Если я добавлю services.AddSingleton(new System.Diagnostics.DiagnosticListener("diagnostic listener"));, я смогу использовать endpoints.MapHub(..) без ошибок, но теперь 1060 * без ошибок вызов http://8090/check возвращает 500 внутреннюю ошибку, поэтому я не думаю, что это правильный путь для решения проблемы.

Я нашел пример использования WebApp от Microsoft.Owin.hosting .
Требуется Microsoft.Owin.4.1.0 , Microsoft.Owin.Hosting.4.1.0 и Owin.1.0.0 , а для последнего требуется Net Framework 4.6.1, я не хочу этого.
Я включил Microsoft.AspNetCore.Owin.3.1.2 (100%. NET Core), но это не предлагает WebApp или что-то подобное.

...