首页 > 解决方案 > SignalR client doesn't connect to server with http protocol

问题描述

I've made .NET Core API with signalR, when I load app with https protocol, I can connect with signalR javascript client, but when I load app with http protocol - signalR js client can't connect to hub. CORS works fine.

My Code: Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy("CorsPolicy",
            builder => builder.WithOrigins("http://localhost:3000")
                .AllowAnyMethod()
                .AllowCredentials()
                .AllowAnyHeader());
    });
    services.AddSignalR(options =>
    {
        options.EnableDetailedErrors = true;
    });
    services.AddControllers(options =>
    {
        options.EnableEndpointRouting = true;
    });
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
{
    logger.LogInformation($"Started Configure with is Production mode:{env.IsProduction()}");
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    app.UseDefaultFiles();
    app.UseStaticFiles();
    app.UseRouting();
    app.UseCors("CorsPolicy");
    app.UseAuthorization();
    app.UseAuthentication();
    app.UseEndpoints(route =>
    {
        route.MapHub<ConnectionHub>("/chat");
        route.MapControllers();
    });
}

On my JS app:

var connection = new signalR.HubConnectionBuilder()
          .withUrl("http://localhost:5066/chat") // WHEN I'M CHANGING TO HTTPS host - everything works fine
          .build();

// Create a function that the hub can call to broadcast messages.
connection.on("broadcastMessage", function (name, message) { });

connection.start()
    .then(function () {       
       connection.invoke("Send", name, messageInput.value); 
    })
    .catch((error) => {
       console.error(error.message);
    });

标签: asp.net-coresignalrasp.net-core-signalr

解决方案


好吧,我解决了这个问题,将选项对象添加到 signalR 客户端(添加 skipNegotiations:true)。老实说,我还不知道它是什么意思(明天我将阅读含义并写下此属性的描述)。

// Start the connection.
        var connection = new signalR.HubConnectionBuilder()
          .withUrl("http://localhost:5066/chat", {
            skipNegotiation: false,
            transport: signalR.HttpTransportType.WebSockets| 
                       signalR.HttpTransportType.LongPolling |
                       signalR.HttpTransportType.serverSentEvents,
          })
          .build();

UPD:嗯,由于在 url 字符串后添加选项对象,它变得有效。关于这个对象。首先 signalR 进行协商(就像前后之间的一些握手),如果传输类型只是 websockets - 你应该跳过它。


推荐阅读