SignalR multiple chat rooms
You don't have to open multiple connections, just one, but to use Group
:
public class MyHub : Hub, IDisconnect
{
public Task Join()
{
return Groups.Add(Context.ConnectionId, "foo");
}
public Task Send(string message)
{
return Clients["foo"].addMessage(message);
}
public Task Disconnect()
{
return Clients["foo"].leave(Context.ConnectionId);
}
}
One group means one room, so every time one user joins one room, you just add that user to the group of that room, and when you want to broadcast message, just send the message to the clients in the group.
More details: https://github.com/SignalR/SignalR/wiki/Hubs
Okay... Here's the simplest way to make multiple rooms:
$(function () {
var chat = jQuery.connection.chat;
chat.addMessage = function (message, room) {
if ($('#currentRoom').val() == room) {
$('#messagesList').append('<li>' + message + '</li>');
}
};
chat.send($('#textboxMessage').val(), $('#currentRoom').val());
$('#textboxMessage').val("");
$.connection.hub.start();
});
public class Chat : Hub
{
public void Send(string msg, string room)
{
Clients.addMessage(msg, room);
}
}
I have a dropdown list of available rooms, and the selected room will be the value of an element, let's say a textbox:
<input type="text" readonly="readonly" id="currentRoom" />
Now, every time .send is called, we will pass not just the message, but also the current room...
The .addMessage will return two values to every client, one is the message, the other is a room... Now we will compare the returned 'room' to the current room of the client. Once they match, the message will be displayed in that current room:
if ($('#currentRoom').val() == room) {
$('#messagesList').append('<li>' + message + '</li>');
}
Simple signalr sample: Visit https://docs.microsoft.com/en-us/aspnet/core/tutorials/signalr?view=aspnetcore-3.1&tabs=visual-studio
then change chat.js
document.getElementById("sendButton").addEventListener("click", function (event) {
var user = document.getElementById("userInput").value;
var message = document.getElementById("messageInput").value;
var room = document.getElementById("room").value;
connection.invoke("SendMessage", user, message,room,false).catch(function (err) {
return console.error(err.toString());
});
event.preventDefault();
});
document.getElementById("joinButton").addEventListener("click", function (event) {
var room = document.getElementById("room").value;
var user = document.getElementById("userInput").value;
var message = document.getElementById("messageInput").value;
connection.invoke("SendMessage", user, message, room,true).catch(function (err) {
return console.error(err.toString());
});
event.preventDefault();
});
edite the ChatHub.cs file with the following code:
using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;
namespace SignalRChat.Hubs
{
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message, string room, bool join)
{
if (join)
{
await JoinRoom(room).ConfigureAwait(false);
await Clients.Group(room).SendAsync("ReceiveMessage", user, " joined to " + room).ConfigureAwait(true);
}
else
{
await Clients.Group(room).SendAsync("ReceiveMessage", user, message).ConfigureAwait(true);
}
}
public Task JoinRoom(string roomName)
{
return Groups.AddToGroupAsync(Context.ConnectionId, roomName);
}
public Task LeaveRoom(string roomName)
{
return Groups.RemoveFromGroupAsync(Context.ConnectionId, roomName);
}
}
}
Html sample:
<div class="container">
<div class="row"> </div>
<div class="row">
<div class="col-2">Room</div>
<div class="col-4"><input type="text" id="room" /></div>
</div>
<div class="row"> </div>
<div class="row">
<div class="col-6">
<input type="button" id="joinButton" value="Join Room" />
</div>
</div>
</div>
<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/dist/browser/signalr.js"></script>
<script src="~/js/chat.js"></script>
signalr c# .net core3 chat chatroom