1
votes

I am trying to host a remote SignalR hub. I created a .NET core 3.1 web api application where I have following code in my Startup class.

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

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

    services.AddSignalR();
}

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

    app.UseRouting();
    app.UseStaticFiles();

    app.UseCors("CorsPolicy");

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapHub<KappHub>("/myHub");
    });
}

CORS should be enabled to accept every origin. In this project, I created a static index.html file.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <h1>Kapp Folc Local Tester</h1>
    <script src="js/signalr/dist/browser/signalr.js"></script>
    <script>
        var connection = new signalR.HubConnectionBuilder().withUrl("/myHub").build();

        connection.start().then(function () {
            console.log('OK');
        }).catch(function (err) {
            console.log(err);
        });
    </script>
</body>
</html>

This works fine! when I dive into developer tools, I can see my web page posting to https://localhost:5001/myHub/negotiate?negotiateVersion=1 and I'm getting a 200 response back. SignalR works great here!

When I use postman or any other REST client, to post to https://localhost:5001/myHub/negotiate?negotiateVersion=1, it works fine and I get a response.

Now I create a second .NET core web api project, also containing a static index.html file, together with signalr.js script. This project however, is not hosting a SignalRhub, but I'm trying to connect to the signalR hub from my first project instead. The index.html is an exact copy of the html from my first project, but with a connection string to the signalR hub from my first project. It looks like this:

var connection = new signalR.HubConnectionBuilder().withUrl("https://localhost:5101/myHub").build();

The startup in my second project looks like this:

public IConfiguration Configuration { get; }

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

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

    app.UseRouting();
    app.UseStaticFiles();

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

When I run this project and I navigate to the index.html from my second project, it's unable to connect to the signalR hub from my first project. In developer tools, I get a "(failed)net::ERR_FAILED" status back without any other information.

The examples above are using SSL (https). Also when running both solutions in http mode, I experience the same problem.

1
Read up on SignalR and CORS in docs.microsoft.com/aspnet/core/signalr/… Specifically, you're missing the AllowCredentials() part, and AllowAnyOrigin will not work with AllowCredentials.Brennan

1 Answers

1
votes

Set your CORS like this:

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

Note that the order!