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!
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>
)
}