I am trying to add SignalR to an existing .NET 6 web application, following the standard guide produced by Microsoft
The use case I am trying to accomplish is this. Its a sports statistics fucntion whereby a timer is started on a mobile device, and the timer runs on a remote device (TV) and this differs on a match by match basis.
So a user on a mobile phone is on a page in the web app at /scorecard/{matchid}/. On a TV screen (or many really, any other listeners) is another webpage running on /bigscreen/{matchid}. When the user presses a button on the mobile phone, a message is sent to the page running on the TV.
The code below works as a static hub, however I am modifying it to try and use similar routes, the {id} value will be different depending on the match being used.
How can I make the existing SignalR hub to be a bit more dynamic based upon the matchid value?
Web Page Controller
[HttpGet("/signalrtest/test/{matchid}")]
public async Task<IActionResult> Index(int matchid)
{
ScoreboardViewModel vm = new ScoreboardViewModel();
vm.MatchId = matchid;
return View(vm);
}
Web Page Razor
@model ScoreboardViewModel
@{
ViewData["Title"] = "SignalR Test";
Layout = "~/Views/Shared/_LayoutLogin.cshtml";
}
<div class="container">
<div class="row"> </div>
<div class="row">
<div class="col-2">User</div>
<div class="col-4"><input type="text" id="userInput" /></div>
</div>
<div class="row">
<div class="col-2">Message</div>
<div class="col-4"><input type="text" id="messageInput" /></div>
</div>
<div class="row"> </div>
<div class="row">
<div class="col-6">
<input type="button" id="sendButton" value="Send Message" />
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<hr />
</div>
</div>
<div class="row">
<div class="col-6">
<ul id="messagesList"></ul>
</div>
</div>
<script src="~/js/signalr.js"></script>
<script type="text/javascript">
"use strict";
var connection = new signalR.HubConnectionBuilder().withUrl("/signalrtesthub/@Model.MatchId").build();
//Disable the send button until connection is established.
document.getElementById("sendButton").disabled = true;
connection.on("ReceiveMessage", function (user, message) {
var li = document.createElement("li");
document.getElementById("messagesList").appendChild(li);
// We can assign user-supplied strings to an element's textContent because it
// is not interpreted as markup. If you're assigning in any other way, you
// should be aware of possible script injection concerns.
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();
});
</script>
Signal R Hub Class
public class SignalRHub : Hub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
Startup.cs
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<SignalRHub>("/signalrtesthub/{matchid}");
});