Failed to complete negotiation with the server when connecting to .NET 6.0 and SignalR backend from ReactJS frontend

Viewed 100

I am trying to create a simple SignalR web application using .NET 6.0 for my backend, and ReactJS for my frontend. However, every time I run the project, I get an error in my console about how there was failure to complete negotiation with the server. Image of error message: Error message

Relevant part of my Program.cs file (no Startup.cs in .NET 6.0):

using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer;
using SignalR.Hubs;

// SET FALSE TO USE RAZOR PAGES
var useReact = true;
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
{
    builder
    .AllowAnyMethod()
    .AllowAnyHeader()
    .AllowCredentials()
    //.AllowAnyOrigin()
    .WithOrigins("http://localhost:32546", "https://localhost:7146");
}));

builder.Services.AddSignalR();
builder.Services.AddControllers();
builder.Services.AddRazorPages();
builder.Services.AddMvc(options =>
{
    options.EnableEndpointRouting = false;
});

builder.Services.AddSpaStaticFiles(config =>
{
    config.RootPath = "clientapp/build";
});

builder.Services.AddScoped<IChatHub, ChatHub>();

var env = builder.Environment;

var app = builder.Build();

app.UseStaticFiles();
app.UseHttpsRedirection();
app.UseWebSockets();
app.MapRazorPages();

if (useReact)
{
    app.UseCors();
    app.UseSpa(spa =>
    {
        spa.Options.SourcePath = "clientapp";

        if (env.IsDevelopment())
        {
            spa.UseReactDevelopmentServer(npmScript: "start");
        }
    });
}

app.UseRouting();
app.MapControllers();

app.MapHub<ChatHub>("chathub");

app.UseMvc();

app.Run();

Relevant part of my ReactJS code:

import './App.css';
import React, { useState, useEffect } from 'react';
import * as signalR from '@microsoft/signalr';

const connection = new signalR.HubConnectionBuilder()
  .configureLogging(signalR.LogLevel.Debug)
  .withUrl("chathub")
  .build();

export default function App() {
  const [messageInput, setMessageInput] = useState("");
  const [userInput, setUserInput] = useState("");
  const [allMessages, updateAllMessages] = useState([]);
  
  useEffect(() => {
    connection.start().then(() => {
      console.log("Connected!");

      connection.on("SendMessage", (message) => {
        updateAllMessages(allMessages.concat(<li>{message}</li>));
      });

    }).catch((err) => {
      return console.error(err.toString());
    });
  })

  const sendMessage = async () =>{
    const chat = {
      user: userInput,
      message: messageInput
    };

    if(connection.connectionStarted){
      try{
        await connection.send("SendMessage", chat);
      }
      catch(e){
        console.log(e);
      }
    }
  };

  const setUserName = (event) => {
    setUserInput(event.target.value);
  }

  const setMessageBody = (event) => {
    setMessageInput(event.target.value);
  }

  const formatAllMessagesToTable = () => {
    return allMessages.map(element => {
      return element;
    })
  }

  return(
    <div className="main">
        <div className="row">
          <div className="col-12">
            <label htmlFor="input-user">User</label>
            <input type="text" id="input-user" onChange={setUserName}/>
          </div>
        </div>
        <div className="row">
          <div className="col-12">
            <label htmlFor="input-message">Message</label>
            <input type="text" id="input-message" onChange={setMessageBody}/>
          </div>
        </div>
        &nbsp;
        <div className="row">
          <div className="col-6">
            <button className="btn btn-primary button" onClick={sendMessage}>
              Send message
            </button>
          </div>
        </div>
        <hr />
        <div className="row">
          <div className="col-6">
            <ul id="messagesList">
              {formatAllMessagesToTable()}
            </ul>
          </div>
        </div>
    </div>
  );
};

I have suspicions that this is related to CORS. I have tried modifying the CORS part of Program.cs in all kinds of ways, but the error prevails. I also have some razor pages set up, after following Microsofts tutorial on setting up SignalR with .NET 6.0, and with those the application works flawlessly. But I want to use ReactJS for my frontend instead, and this is where the problems arose.

0 Answers
Related