I have an ASP.NET Webforms application (running on .NET 4.8) and a an ASP.NET Core 7 MVC app. I want to establish a SignalR connection from the Webforms app to the one in MVC, such that when the clients on Webforms log in, they update the hub on MVC.
That is, the hub is on the MVC app, and I want to broadcast information to the clients on Webforms. I already have the logic to send messages to the clients at the hub from the MVC app, but I haven't been able to connect from the Webforms client (i.e. from JavaScript) to the hub in the other application.
My client code to establish a connection in Webforms is as follows:
$(document).ready(function () {
var connection = $.hubConnection();
connection.url = "https://localhost:44312/chatHub";
var myChatHubProxy = connection.createHubProxy('chatHub');
connection.start()
.done(function () {
// Logic on connection start
})
.fail(function (err) {
console.error(err);
});
// Additional code.
});
Where https://localhost:44312/chatHub
is the URL from the MVC app. The error I'm getting is
Error during negotiation request
and in the stacktrace there are just references to the JavaScript SignalR file.
After my test, you can use the same version of signalR client version as that of asp.net Core SignaleR Hub, and you need to configure the corresponding cross-domain strategy. The following example can be used as a reference:
Firstly, the signalR Hub is established through this document and the corresponding routing node :document1 , document2
Secondly, you can use the cdn directly by quoting the same version of asp.net Core signalR in the webform.
< script src = https://cdnjs.cloudflare.com/Ajax/libs/Microsoft-signalr/6.0.1/signalr.js > </script >
or download in the document.
I realize the related connection part through chat.js
:
My webforms chat.js:
"use strict";
const connection = new signalR.HubConnectionBuilder()
.withUrl(https://localhost:7105/chatHub, {
withCredentials: false
})
.configureLogging(signalR.LogLevel.Information)
.build();
document.getElementById("sendButton").disabled = true;
connection.on("ReceiveMessage", function (user, message) {
var li = document.createElement("li");
document.getElementById("messagesList").appendChild(li);
li.textContent = `${user} says ${message}`;
});
connection.start().then(function () {
document.getElementById("sendButton").disabled = false;
}).catch(function (err) {
return console.error(err.toString());
});
document.getElementById("sendButton").addEventListener("click", function (event) {
var user = document.getElementById("userInput").value;
var message = document.getElementById("messageInput").value;
connection.invoke("SendMessage", user, message).catch(function (err) {
return console.error(err.toString());
});
event.preventDefault();
});
My webform index:
<!DOCTYPE html>
<html>
<head>
<title>SignalR Simple Chat</title>
<style type="text/css">
.container {
background-color: #99CCFF;
border: thick solid #808080;
padding: 20px;
margin: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="row p-1">
<div class="col-1">User</div>
<div class="col-5"><input type="text" id="userInput" /></div>
</div>
<div class="row p-1">
<div class="col-1">Message</div>
<div class="col-5"><input type="text" class="w-100" id="messageInput" /></div>
</div>
<div class="row p-1">
<div class="col-6 text-end">
<input type="button" id="sendButton" value="Send Message" />
</div>
</div>
<div class="row p-1">
<div class="col-6">
<hr />
</div>
</div>
<div class="row p-1">
<div class="col-6">
<ul id="messagesList"></ul>
</div>
</div>
</div>
<script src=https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/6.0.1/signalr.js></script>
<script src="Scripts/Chat.js"></script>
</body>
</html>
My asp.net core program.cs:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSignalR();
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder.WithOrigins(https://localhost:44330)
.AllowAnyHeader()
.WithMethods("GET", "POST")
.AllowCredentials();
});
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseCors();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapHub<ChatHub>("/chatHub");
app.Run();
asp.net core ChatHub.cs :
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
Once the program is launched, signalR can be linked correctly: