2

I am trying to get a signalR connection with my react app, I have created the hub in asp .net core, but it wont seem to work in my frontend.

I am new when it comes to signalR, but I have created this before, with an asp .net core MVC application, so I know the logic works.

But I have never done anything with signalR using React. So thats why I could need some help.

Let me show you some code SignalR Hub

public class OnConnectionHub : Hub
    {
        public static int ConnectionCount { get; set; }

        public override Task OnConnectedAsync()
        {
            ConnectionCount++;
            Clients.All.SendAsync("updateConnectionCount", ConnectionCount).GetAwaiter().GetResult();
            return base.OnConnectedAsync();
        }

        public override Task OnDisconnectedAsync(Exception? exception)
        {
            ConnectionCount--;
            Clients.All.SendAsync("updateConnectionCount", ConnectionCount).GetAwaiter().GetResult();
            return base.OnDisconnectedAsync(exception);
        }
    }

Fairly simple, just increment and decrement on the OnConnectedAsync and OnDisconnectedAsync

This the hub url I created

endpoints.MapHub<OnConnectionHub>("hubs/onConnectionHub");

And here is some code in my react component

import { HubConnectionBuilder } from "@microsoft/signalr"
import { useState } from "react"

export const ConnectionCount = () => {
    const [connectionCount, setConnectionCount] = useState(0)
    // create connection
    const connection = new HubConnectionBuilder()
        .withUrl("https://localhost:7199/hubs/onConnectionHub")
        .build()

    // connect to method that hub invokes
    connection.on("updateConnectionCount", (onConnection) => {
        setConnectionCount(onConnection)
        }
    )

    // start connection
    connection.start();

    return <p>Active members {connectionCount}</p>
}

The errors I get

react_devtools_backend.js:4026 [2022-07-14T08:31:46.444Z] Error: Failed to complete negotiation with the server: TypeError: Failed to fetch
client.onmessage @ WebSocketClient.js:50
2HttpConnection.ts:350 Uncaught (in promise) Error: Failed to complete negotiation with the server: TypeError: Failed to fetch
    at HttpConnection._getNegotiationResponse (HttpConnection.ts:350:1)
    at async HttpConnection._startInternal (HttpConnection.ts:247:1)
    at async HttpConnection.start (HttpConnection.ts:138:1)
    at async HubConnection._startInternal (HubConnection.ts:206:1)
    at async HubConnection._startWithStateTransitions (HubConnection.ts:180:1)

Thanks!

Joro
  • 311
  • 4
  • 15
  • 1
    What do you see in your browser's DevTools' Network window? – Dai Jul 15 '22 at 06:13
  • 1
    Thanks for your comment, I dont really see anything of use, nothing with signalR – Joro Jul 18 '22 at 16:06
  • 1
    Pls make sure you have enable CROS in your .net core application. And you also can try to use [`skipNegotiation: true`](https://stackoverflow.com/a/52913505/7687666). – Jason Pan Jul 19 '22 at 09:33

1 Answers1

3

Solved it by updating the corspolicy a bit like this

builder.Services.AddCors(options =>
{
    var frontendUrl = builder.Configuration.GetValue<string>("frontend_url");
    options.AddPolicy("allowConnection", builder =>
    {
        builder.WithOrigins(frontendUrl)
            .AllowAnyMethod()
            .AllowAnyHeader()
            .AllowCredentials()
            .WithExposedHeaders(new string[] { "totalAmountOfRecords" });
    });
});

Creating a policy instead of default policy And

app.UseCors("allowConnection");

Also, in the frontend

import { HubConnectionBuilder } from "@microsoft/signalr"
import { useEffect, useState } from "react"

export const ConnectionCount = () => {
    const [connectionCount, setConnectionCount] = useState(0)
    // create connection
    useEffect(() => {
        const connection = new HubConnectionBuilder()
        .withUrl("https://localhost:7199/hubs/onConnectionHub")
        .build()

    // connect to method that hub invokes
    connection.on("updateConnectionCount", (onConnection) => {
        setConnectionCount(onConnection)
        }
    )

    // start connection
    connection.start().then(() => {
        console.log("Connection started")
    });
    }, [])
    

    return(
        <section>
            <p>Active connections: {connectionCount}</p>
        </section>
    )
}
Joro
  • 311
  • 4
  • 15