SignalR Core работает на локальном хосте, но не в службе приложений Azure.

У меня есть клиентская программа (приложение WPF в .Net 4.8) и веб-API (.Net Core 3.1). Я пытаюсь заставить их общаться через SignalR Core. Он отлично работает, когда оба работают локально на моем ПК (то есть на localhost). Но как только я публикую свой API в службе приложений Azure (и указываю приложению WPF новый URL-адрес), он перестает работать. SignalR устанавливает соединение, но когда API отправляет данные в приложение WPF, приложение никогда их не получает.

Я не уверен, связано ли это с CORS. CORS в службе приложений Azure отключен. В моем веб-API я использую этот Startup.cs:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();

        services.AddCors(options =>
        {
            options.AddPolicy(MyAllowSpecificOrigins,
                builder => builder
                .AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader()                    
                );
        });

        string connectionString = Configuration.GetConnectionString("eBallDatabase");
        services.AddDbContext<EBallContext>(options =>
                options.UseSqlServer(connectionString));

        var config = new AutoMapper.MapperConfiguration(cfg =>
        {
            cfg.AddProfile(new AutoMapperProfileConfiguration());
        });
        var mapper = config.CreateMapper();
        services.AddSingleton(mapper);

        services.AddSignalR(options =>
        {
            options.EnableDetailedErrors = true;
        });

        services.AddApplicationInsightsTelemetry();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseCors("corsPolicy");
        app.UseHttpsRedirection();
        app.UseRouting();
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapHub<ChatHub>("/chatHub");
        });
    }

Я думаю, что однажды прочитал, что у вас не может быть AllowAnyOrigin () с SignalR. Вам необходимо указать желаемое происхождение. Но я не уверен, каково мое происхождение, поскольку это приложение WPF, работающее на компьютерах разных пользователей, все с разными доменами / IP-адресами.

Как я уже сказал, он отлично работает, когда все находится на loclahost. Но как только API находится в службе приложений Azure, им обоим удается установить соединение SignalR, но это все. Приложение WPF не получает данных от API.

Любые идеи?


person Fabricio Rodriguez    schedule 27.01.2020    source источник


Ответы (1)


Да, вам нужно указать происхождение. И порядок CORS методов тоже имеет значение. И вам нужен CORS для связи между вашим приложением Framework и приложением .NET Core. Итак, вы можете попробовать это:

services.AddCors(options =>
{
    options.AddPolicy(CorsPolicy, builder => builder.WithOrigins("https://yourFrameworkApp.azurewebsites.com")
        .AllowAnyHeader()
        .AllowAnyMethod()
        .AllowCredentials()
        .SetIsOriginAllowed((host) => true));
});

Также вы можете увидеть на стороне клиента, какая у вас ошибка при подключении к хабу. Например, когда клиентская сторона вызывает конечную точку в ваш концентратор для согласования, вы можете иметь:

CORS ошибка - попробуйте добавить, как показано ниже.

404 не найден - вы указываете не на тот контроллер / концентратор.

405 метод не разрешен - это когда пользователь не авторизован для вызова методов в вашем хабе.

Кроме того, при запуске (метод настройки) проверьте, добавляете ли вы веб-сокеты:

app.UseWebSockets();

Изменить: вы также можете попробовать использовать Azure SignalR, чтобы не беспокоиться об этом типе проблем.

person Kiril1512    schedule 27.01.2020
comment
Спасибо за ответ Kiril512. Я попробую, когда буду дома. Быстрый вопрос: когда вы говорите, что я должен указать Origin как yourFrameworkApp.azurewebsites.com, это URL, по которому API размещен? Или это URL-адрес приложения WPF? Поскольку у приложения WPF нет URL-адреса - это приложение Windows, работающее на компьютерах разных пользователей ... - person Fabricio Rodriguez; 28.01.2020
comment
Кроме того, как ни странно, я не получаю сообщение об ошибке, когда приложение WPF подключается к концентратору SignalR. Соединение действительно установлено. Но затем, когда API пытается отправить данные SignalR в приложение WPF, приложение WPF не получает данные. (За исключением случаев, когда API также работает на локальном хосте, приложение WPF получает данные) - person Fabricio Rodriguez; 28.01.2020
comment
@FabricioRodriguez yourFrameworkApp.azurewebsites.com - это место, где размещается приложение, а не клиентское приложение WPF. - person Kiril1512; 28.01.2020
comment
Итак, где размещен API? Извините, пытаюсь понять .. - person Fabricio Rodriguez; 28.01.2020
comment
@FabricioRodriguez, у вас есть два приложения. Одно из них - это ваше приложение .NET FW 4.8, а другое - приложение .NET Core 3.1. Оба они представляют собой веб-приложения, размещенные на лазурном сервере. Вы должны получить URL-адрес своего приложения .NET FW для добавления в CORS. - person Kiril1512; 28.01.2020
comment
Ой, может, я что-то упускаю. У меня есть только одно приложение, размещенное в службе приложений Azure - веб-API (.Net Core 3.1). Другое приложение - клиентское приложение - представляет собой обычное приложение Windows, написанное на C # / WPF (.Net 4.8), которое устанавливается на компьютеры пользователей. Он вообще не размещается в Azure. Но может я что-то недопонимаю ... - person Fabricio Rodriguez; 28.01.2020
comment
@FabricioRodriguez хорошо, теперь я понимаю. У вас есть междоменные запросы к вашему приложению .NET Core 3.1 от этих приложений WPF. Вы сказали, что он правильно подключается к хабу. Вы пытались использовать Azure SignalR, чтобы проверить, все ли вы получаете данные? - person Kiril1512; 28.01.2020
comment
Давайте продолжим это обсуждение в чате. - person Kiril1512; 28.01.2020
comment
Спасибо Kiril512. Не знаю почему, но использую .SetIsOriginAllowed ((host) = ›true)); сделал это! В какой-то момент у меня было что-то похожее: .SetIsOriginAllowed (_ = ›true)); который никогда не работал ... - person Fabricio Rodriguez; 28.01.2020
comment
@FabricioRodriguez очень мило. Удачи с проектом! - person Kiril1512; 29.01.2020