Group in SignalR

Add Remove example

public async Task AddToGroup(string groupName)
{
    await Groups.AddToGroupAsync(Context.ConnectionId, groupName);

    await Clients.Group(groupName).SendAsync("Send", $"{Context.ConnectionId} has joined the group {groupName}.");
}

public async Task RemoveFromGroup(string groupName)
{
    await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);

    await Clients.Group(groupName).SendAsync("Send", $"{Context.ConnectionId} has left the group {groupName}.");
}

Chat Group example

Models

public class ChatMessage
{
	public string SenderName { get; set; }

	public string Text { get; set; }

	public DateTimeOffset SentAt { get; set; }
}

public class ChatRoom
{
	public string OwnerConnectionId { get; set; }
}

Services

public interface IChatRoomService
{
	Task<Guid> CreateRoom(string connectionId);

	Task<Guid> GetRoomForConnectionId(string connectionId);
}

public class InMemoryChatRoomService : IChatRoomService
{
	private readonly Dictionary<Guid, ChatRoom> _roomInfo
		= new Dictionary<Guid, ChatRoom>();

	public Task<Guid> CreateRoom(string connectionId)
	{
		var id = Guid.NewGuid();
		_roomInfo[id] = new ChatRoom
		{
			OwnerConnectionId = connectionId
		};

		return Task.FromResult(id);
	}

	public Task<Guid> GetRoomForConnectionId(string connectionId)
	{
		var foundRoom = _roomInfo.FirstOrDefault(
			x => x.Value.OwnerConnectionId == connectionId);

		if (foundRoom.Key == Guid.Empty)
			throw new ArgumentException("Invalid connection ID");

		return Task.FromResult(foundRoom.Key);
	}
}

Now, dependency injection in Startup class: services.AddSingleton<IChatRoomService, InMemoryChatRoomService>();

ChatHub.cs

public class ChatHub : Hub
{
	private readonly IChatRoomService _chatRoomService;

	public ChatHub(IChatRoomService chatRoomService)
	{
		_chatRoomService = chatRoomService;
	}

	public override async Task OnConnectedAsync()
	{
		var roomId = await _chatRoomService.CreateRoom(Context.ConnectionId);

		await Groups.AddToGroupAsync(Context.ConnectionId, roomId.ToString());

		await Clients.Caller.SendAsync(
			"ReceiveMessage",
			"Foo",
			DateTimeOffset.UtcNow,
			"bar");

		await base.OnConnectedAsync();
	}

	public async Task SendMessage(string name, string text)
	{
		var roomId = await _chatRoomService.GetRoomForConnectionId(Context.ConnectionId);

		var message = new ChatMessage
		{
			SenderName = name,
			Text = text,
			SentAt = DateTimeOffset.UtcNow
		};

		// Broadcast to all clients
		await Clients.Group(roomId.ToString()).SendAsync(
			"ReceiveMessage",
			message.SenderName,
			message.SentAt,
			message.Text);
	}
}