与 asp.net 应用程序和子文件夹协商时出现 SignalR 错误 404

SignalR error 404 on negotiate with asp.net application and subfolder

我正在使用 ASP.NET Core 3.1,SignalR 3.1.9:

我正在使用 Javscript 客户端 v3.1.9(libman.json 文件):

    {
      "provider": "unpkg",
      "library": "@microsoft/signalr@3.1.9",
      "destination": "wwwroot/lib/signalr/",
      "files": [
        "dist/browser/signalr.js",
        "dist/browser/signalr.min.js"
      ]
    }

在我的网络服务器上,根 (example.com) 被 Wordpress 用作前端。 Wordpress 允许在 web.config 中对 /core 进行一些修改,并且网站加载正确 100%。

为了托管我的 .NET Core 应用程序,我创建了一个指向子文件夹 core 的应用程序(示例。com/core)。我不知道这是否重要,但我所有的控制器都在“app”区域下(示例。com/core/app)。

我声明了一个新的 Hub:

    public class NotificationsHub : Hub
    {
        private readonly IMainDataService _data;
        private readonly ILogger<NotificationsHub> _logger;

        public NotificationsHub(IMainDataService data, ILoggerFactory loggerFactory)
        {
            this._data = data;
            this._logger = loggerFactory.CreateLogger<NotificationsHub>();
        }

        public async Task SendFriendNotification(Guid newFriendId, Guid currentUserId)
        {
            var currentUser = await this._data.GetUserByIdAsync(currentUserId);
            var notificationRecipientId = newFriendId.ToString();
            await Clients.User(notificationRecipientId).SendAsync("FriendRequestReceived", newFriendId, currentUserId, currentUser.FirstName, currentUser.LastName);
        }

这是我的Startup.cs(缩写为基本内容):

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

            services.Configure<CookiePolicyOptions>(options =>
            {
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
                options.ConsentCookie.Expiration = TimeSpan.FromDays(365);
            });

            services.AddMicrosoftIdentityWebAppAuthentication(Configuration, "AzureAdB2C");

            services.AddControllersWithViews()
                .AddMvcLocalization()
                .AddMicrosoftIdentityUI();

            services.AddRazorPages();
            services.AddSignalR();
            services.AddRouting();

            services.AddOptions();

            services.Configure<OpenIdConnectOptions>(Configuration.GetSection("AzureAdB2C"));

            services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();

            services.AddDistributedMemoryCache();

            services.AddSession(options =>
            {
                options.Cookie.IsEssential = true;
            });
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            // ...

            if ((env.IsDevelopment() || env.IsStaging() || env.IsProduction()) && !env.IsEnvironment("Localhost"))
            {
                app.UsePathBase("/core");
            }

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();

                endpoints.MapControllerRoute(
                    name: "areas",
                    pattern: "{area:exists}/{controller=Map}/{action=Index}/{id?}"
                );
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{area=App}/{controller=Map}/{action=Index}"
                );
                endpoints.MapControllerRoute(
                    name: "profile",
                    pattern: "{area=App}/{controller=Profile}/{action=Index}/{id?}"
                );

                endpoints.MapRazorPages();

                endpoints.MapDbLocalizationAdminUI();
                endpoints.MapDbLocalizationClientsideProvider();

                if (env.EnvironmentName == "Localhost")
                {
                    endpoints.MapHub<NotificationsHub>("/notificationshub");
                }
                else
                {
                    endpoints.MapHub<NotificationsHub>("/core/notificationshub");
                }
            });
        }

在本地,因为我直接 运行 我的 .NET Core 应用在根目录下,没有问题。但是当我部署到Dev/Staging/Prod,使用子文件夹/core时,我总是在以下URL上得到错误404:https://www.example.com/core/notificationshub/negotiate?negotiateVersion=1

我也试过:

在这两种情况下,我都会收到 404 异常。在 F12 控制台中,404 始终跟在以下行之后:

Error: Failed to complete negotiation with the server: Error: Not Found
Error: Failed to start the connection: Error: Not Found
Error: Not Found

上面的第 3 行指向我的 JavaScript 客户:

"use strict";

var currentUrl = window.location.href;

var basePath = '';
if (currentUrl.includes("/core") == true) {
    basePath = '/core'
}

var connection = new signalR.HubConnectionBuilder().withUrl(basePath + "/notificationshub").build();

connection.start().catch(function (err) {
    return console.error(err.toString());
});

错误在 connection.start() 行。

我试图在路径前用 ../ 修改上一行,但没有帮助:

let connection = new signalR.HubConnectionBuilder().withUrl("../" + basePath + "/notificationshub").build();

知道我是否遗漏了什么吗?让 SignalR 在根 URL 上工作似乎很简单,但如果有子文件夹则不然。

您似乎正在将您的应用映射到“/core”,然后将您的中心映射到“/core/hub”。所以你的集线器实际上是在“/core/core/hub”。