Connecting NodeJS app to SignalR (with .NET Core 3)

Tags: , , , ,



I have a server running SignalR using .NET Core 3. The project was started with the template and I followed a guide (https://docs.microsoft.com/en-gb/aspnet/core/tutorials/signalr?tabs=visual-studio&view=aspnetcore-3.0).

I have created a clone of the project, and can successfully connect to the server and can receive messages as expected. This also means I added CORS.

I want to be able to use SignalR in a Node JS environment, but the connection stucks at “Negotiation” I have created a brand new folder, ran npm init -y and npm i @microsoft/signalr. Created a new js file called main.js, which looks like this:

const signalR = require("@microsoft/signalr");

let connection = new signalR.HubConnectionBuilder()
    .withUrl("http://localhost:44336/chathub")
    .configureLogging(signalR.LogLevel.Trace)
    .build();

connection.on("send", data => {
    console.log(data);
});

connection.start()
    .then(() => connection.invoke("send", "Hello"));

after running it with node main.js I get the following error in console

[2019-11-26T14:56:14.933Z] Debug: Starting HubConnection.
[2019-11-26T14:56:14.935Z] Debug: Starting connection with transfer format 'Text'.
[2019-11-26T14:56:14.936Z] Debug: Sending negotiation request: http://localhost:44336/chathub/negotiate.
[2019-11-26T14:58:18.890Z] Warning: Error from HTTP request. Error: read ECONNRESET
[2019-11-26T14:58:18.891Z] Error: Failed to complete negotiation with the server: Error: read ECONNRESET
[2019-11-26T14:58:18.892Z] Error: Failed to start the connection: Error: read ECONNRESET
[2019-11-26T14:58:18.892Z] Debug: HubConnection failed to start successfully because of error 'Error: read ECONNRESET'.

It seems like it’s timing out. The server, client and nodejs app are all hosted locally. I made sure to check that the signalr version installed with npm i match the version of server (3.0.1). I even extracted the js files in node_modules and used them for another client (made with the VS template) and it can connect just fine.

I have no clue how to debug any further. I tried to attach to the server using VS, but I couldnt get any information. The server is hosted using IIS Express (started via Visual Studio). Any tips on how to debug any further? otherwise I might downgrade to a previous .NET Core version with another signalr version

My startup.cs code in VS

public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            //services.AddControllersWithViews();

            services.AddCors(options =>
            {
                options.AddPolicy("AllowAll",
                    builder =>
                    {
                        builder
                            .WithOrigins("http://localhost:44399", "http://localhost:44336", "https://localhost:44399", "https://localhost:44336")
                            .AllowCredentials()
                            .AllowAnyMethod()
                            .AllowAnyHeader();
                    });
            });

            services.AddSignalR();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }            

            app.UseRouting();
            app.UseCors("AllowAll");
            app.UseEndpoints(endpoints =>
                {
                    endpoints.MapHub<ChatHub>("/chathub");
                });
        }
    }

Answer

Don’t know if this is the root cause or not, but I stumbled on this in my setup.

The default settings for IISExpress in Visual Studio do not listen on the same port for http and https. I was using the SSL port in my node.js file, but using the http protocol. I suspect your problem might be the same, since VS usually defaults to the 44000 range for SSL ports.

What confused me was the fact that my browser would pop up on the SSL port during debugging.

In my case, I checked ./Properties/launchSettings.json to get the ports being used:

  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:63591",
      "sslPort": 44357
    }
  },

Then updated my js file accordingly:

const signalR = require("@microsoft/signalr");

var hubConnection = new signalR.HubConnectionBuilder()
    .configureLogging(signalR.LogLevel.Trace)
    .withUrl("http://localhost:63591/chatHub")
    .build();

And voila. Run the app in Visual Studio 2019, and then on the command line:

davek-win64% node app.js
[2020-08-05T21:20:15.483Z] Debug: Starting HubConnection.
[2020-08-05T21:20:15.490Z] Debug: Starting connection with transfer format 'Text'.
[2020-08-05T21:20:15.491Z] Debug: Sending negotiation request: http://localhost:63591/chatHub/negotiat
e.
[2020-08-05T21:20:15.591Z] Debug: Selecting transport 'WebSockets'.
[2020-08-05T21:20:15.592Z] Trace: (WebSockets transport) Connecting.
[2020-08-05T21:20:15.615Z] Information: WebSocket connected to ws://localhost:63591/chatHub?id=sYmFd19
_rNCR7q3mddpJBA.
[2020-08-05T21:20:15.616Z] Debug: The HttpConnection connected successfully.
[2020-08-05T21:20:15.616Z] Debug: Sending handshake request.
[2020-08-05T21:20:15.619Z] Trace: (WebSockets transport) sending data. String data of length 32.
[2020-08-05T21:20:15.621Z] Information: Using HubProtocol 'json'.
[2020-08-05T21:20:15.633Z] Trace: (WebSockets transport) data received. String data of length 3.
[2020-08-05T21:20:15.634Z] Debug: Server handshake complete.
[2020-08-05T21:20:15.635Z] Debug: HubConnection connected successfully.
Connected!
[2020-08-05T21:20:28.547Z] Trace: (WebSockets transport) data received. String data of length 74.
stackoverflow test
[2020-08-05T21:20:30.637Z] Trace: (WebSockets transport) sending data. String data of length 11.
[2020-08-05T21:20:31.197Z] Trace: (WebSockets transport) data received. String data of length 11.


Source: stackoverflow