SignalR Core在本地主机上运行正常,但在Azure App Service上无法正常工作。

5
我有一个客户端程序 (.Net 4.8上的WPF应用程序)和一个Web API(.Net Core 3.1)。我正在尝试让它们通过SignalR Core进行通信。当两者都在我的PC本地运行时(即在localhost上),它可以完美地工作。但是,一旦我将API发布到Azure App Service(并将WPF应用程序指向新的URL),它就无法正常工作。SignalR建立了连接,但是当API向WPF应用程序发送数据时,应用程序却从未接收到。我不确定是否与CORS有关。Azure App Service上的CORS已禁用。在我的Web 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");
        });
    }

我记得曾经读过一篇文章,说SignalR不能使用AllowAnyOrigin(),需要指定所需的来源。但是我不确定我的来源是什么,因为这是一个在各个用户计算机上运行的WPF应用程序,所有计算机都有不同的域名/IP地址。

就像我说的,在所有东西都在本地主机上时,它可以完美地工作。但是一旦API在Azure App Service上,它们就能够建立SignalR连接,但这就是全部。WPF应用程序没有从API接收到任何数据。

有什么想法吗?

1个回答

4

是的,您需要指定来源。并且 CORS 方法的顺序也很重要。您需要使用 CORS 在框架应用程序和 .NET Core 应用程序之间进行通信。因此,您可以尝试以下操作:

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

此外,您可以在客户端看到连接到中心时出现的错误。例如,当客户端调用端点与您的中心进行协商时,可能会出现以下情况:
CORS 错误 - 尝试像下面这样添加。
404 未找到 - 您指向了错误的控制器/中心。
405 方法不允许 - 当用户无权调用您的中心中的方法时,就会出现此错误。
另外,在您的 Startup(Configure 方法)中检查是否添加了 Web Sockets。
app.UseWebSockets();

编辑:你也可以尝试使用Azure SignalR,这样就不需要担心这种类型的问题了。


感谢您的回复,Kiril512。我会在今晚回家后尝试它。快速问题,当您说我必须将Origin指定为“https://yourFrameworkApp.azurewebsites.com”时,这是API托管的URL吗?还是WPF应用程序的URL?因为WPF应用程序没有URL-它是在各个用户计算机上运行的Windows应用程序... - Fabricio Rodriguez
还有一件有趣的事情,当WPF应用程序连接到SignalR中心时,我竟然没有收到错误。实际上连接成功了。但是,当API尝试向WPF应用程序发送SignalR数据时,WPF应用程序并未接收到数据。(除非API也在本地主机上运行,则WPF应用程序将会接收到数据) - Fabricio Rodriguez
@FabricioRodriguez "yourFrameworkApp.azurewebsites.com" 是应用程序托管的位置,而不是客户端 WPF 应用程序。 - Kiril1512
好的,那么API托管在哪里?抱歉,我正在努力理解... - Fabricio Rodriguez
2
谢谢Kiril512。我不确定为什么,但使用.SetIsOriginAllowed((host) => true));就可以了!曾经有一次我有类似的东西:.SetIsOriginAllowed(_ => true));但从来没有起作用... - Fabricio Rodriguez
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接