Featured
How to Make a Real-Time Chat App With SignalR in ASP.NET 6
Last modified: March 05, 2022Step 1
Create an ASP.NET Razor Page application. Select Individual Account for authentication.
Configure the AppSetting.json to your Database connection string and perform below migration scripts.
add-migration InitialCreate
update-database
Create few users
Step 2
Add the SignalR client library
Right click on Solution => wwwwroot => js and install SignalR client library
Step 3
Create a SignalR hub. SendMessage method is used to send message to all online users whereas SendMessageToGroup only send message to selected receiver.
public class ChatHub : Hub
{
public override Task OnConnectedAsync()
{
Groups.AddToGroupAsync(Context.ConnectionId, Context.User.Identity.Name);
return base.OnConnectedAsync();
}
public async Task SendMessage(string user, string message)
{
//message send to all users
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
public Task SendMessageToGroup(string sender, string receiver, string message)
{
//message send to receiver only
return Clients.Group(receiver).SendAsync("ReceiveMessage", sender, message);
}
}
Step 4
Configure SignalR
In the Program.cs, we need to configure SignalR.
builder.Services.AddSignalR();
app.MapHub<ChatHub>("/chatHub");
Step 5
Add SignalR client code
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
<div class="container">
<div class="row">
<div class="col-2">Receiver</div>
<div class="col-4">@Html.DropDownList("receiver",Model.Users, "All")</div>
</div>
<div class="row">
<div class="col-2">Message</div>
<div class="col-4"><input type="text" id="message" /></div>
</div>
<div class="row">
<div class="col-6">
<input type="button" id="sendMessage" value="Send Message" />
</div>
</div>
<div class="row">
<div class="col-6">
<ul id="messagesList"></ul>
</div>
</div>
</div>
@Html.Hidden("sender", Model.MyUser) <!--Current logged in username-->
@section Scripts
{
<script src="~/js/microsoft/signalr/dist/browser/signalr.js"></script>
<script src="~/js/chat.js" asp-append-version="true"></script>
}
//only authenticated can access this page
[Authorize]
public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;
private readonly UserManager<IdentityUser> _userManager;
[BindProperty]
public List<SelectListItem> Users { get; set; }
[BindProperty]
public string MyUser { get; set; }
public IndexModel(ILogger<IndexModel> logger, UserManager<IdentityUser> userManager)
{
_logger = logger;
_userManager = userManager;
}
public void OnGet()
{
//get all the users from the database
Users = _userManager.Users.ToList()
.Select(a => new SelectListItem { Text = a.UserName, Value = a.UserName })
.OrderBy(s => s.Text).ToList();
//get logged in user name
MyUser = User.Identity.Name;
}
}
In the wwwroot/js folder, create a chat.js file with the following code:
var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
//Disable send button until connection is established
$("#sendMessage").prop('disabled', true);
connection.on("ReceiveMessage", function (user, message) {
var msg = message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
var encodedMsg = user + " says " + msg;
var li = document.createElement("li");
li.textContent = encodedMsg;
$("#messagesList").append(li);
});
connection.start().then(function () {
$("#sendMessage").prop('disabled', false);
}).catch(function (err) {
return console.error(err.toString());
});
$("#sendMessage").click(function () {
var sender = $("#sender").val();
var receiver = $("#receiver").val();
var message = $("#message").val();
if (receiver != "") {
//send to a user
connection.invoke("SendMessageToGroup", sender, receiver, message).catch(function (err) {
return console.error(err.toString());
});
}
else {
//send to all
connection.invoke("SendMessage", sender, message).catch(function (err) {
return console.error(err.toString());
});
}
event.preventDefault();
});
Step 6
Test the application
Login in different tabs and test sending message to each other or group messsage