Search code examples
signalr.clientasp.net-core-signalr

SignalR no transport


Attempting to start signal-r hub reports "Error: No available transports found."

However, a diagnostic capture shows that negotiation returns three available transports.

{
    "connectionId": "IsHpe_1ETRLz-flnJ3uKPg",
    "availableTransports": [
        {
            "transport": "WebSockets",
            "transferFormats": [
                "Text",
                "Binary"
            ]
        },
        {
            "transport": "ServerSentEvents",
            "transferFormats": [
                "Text"
            ]
        },
        {
            "transport": "LongPolling",
            "transferFormats": [
                "Text",
                "Binary"
            ]
        }
    ]
}

This is done with aspnetcore 2.1 preview2 and startup looks like this

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options => options.AddPolicy("AllowAny", x =>
          x.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin()));
        services.AddSignalR();
        services.AddOptions();
        services.Configure<AppSettings>(Configuration);
        var connectionStrings = Configuration.GetSection("ConnectionStrings");
        var defaultConnectionString = connectionStrings[Configuration["DefaultConnectionString"]];
        services.AddDbContext<au1.Model.ProwlerDbContext>(options => 
          options.UseSqlServer(defaultConnectionString));
        services.AddMvc();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseCors("AllowAny");
        app.UseSignalR(routes =>
        {
            routes.MapHub<MessageHub>("/message");
        });
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
            {
                HotModuleReplacement = true
            });
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");

            routes.MapSpaFallbackRoute(
                name: "spa-fallback",
                defaults: new { controller = "Home", action = "Index" });
        });
    }

Obviously the route works, or negotiation wouldn't appear in the network traffic. Invoking http://local:5000/message with a browser produces a message Connection ID required as expected.

Have I left a step out?

On the client side, here's how I've tried to connect.

    this.signalr = new SignalR.HubConnection("http://localhost:5000/message");
    this.signalr.on("stateChange", (data: string) => {
        console.log(`SignalR: ${data}`);
        that.selection = data;
    });
    this.signalr.start().then(result=>{
        console.log("hub started");
    }).catch(err=>{
        console.log("hub failed to start");
    });

package.json says "_id": "@aspnet/[email protected]",

The .csproj says <PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.0.0-preview2-final" />

These are not the same. Whether they are compatible I could not say.

I don't know how these got out of synch as I omitted version to get the latest of each. An npm update brought the client to preview2 and I shall now retest.


Solution

  • The versions of the server and the client have to align. You need to make sure that both client versions are the same by going to your .csproj file (for the version of the server and/or the version of the C# client) and to package.json for the version of the JavaScript/TypeScript client if you installed it using npm.

    Note that there are breaking changes between previews so you cannot use a -previewX client with a previewY server.