Skip to content

Commit

Permalink
Merge pull request #23 from Klustr-RTC/nilesh/random-chat
Browse files Browse the repository at this point in the history
Added SignalR endpoint for random video chat
  • Loading branch information
Nilesh9106 authored Jun 7, 2024
2 parents a0b5e0c + 4265a6e commit 15948cf
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 2 deletions.
16 changes: 16 additions & 0 deletions Dtos/Hub/RandomMessageDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Klustr_api.Dtos.User;

namespace Klustr_api.Dtos.Hub
{
public class RandomMessageDto
{
public required string content { get; set; }
public required UserDto user { get; set; }

public DateTime? timeStamp { get; set; }
}
}
134 changes: 132 additions & 2 deletions Hubs/ChatHub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@

namespace Klustr_api.Hubs
{
public class ChatHub(IDictionary<string, UserRoomConnection> connections) : Hub<IChatClient>
public class ChatHub(List<string> waitingUsers, IDictionary<string, UserRoomConnection> connections, IDictionary<string, string?> randomPairs, IDictionary<string, UserDto> randomUsers) : Hub<IChatClient>
{
private readonly IDictionary<string, UserRoomConnection> _connections = connections;

private readonly IDictionary<string, string?> _randomPairs = randomPairs;
private readonly IDictionary<string, UserDto> _randomUsers = randomUsers;
private List<string> _waitingUsers = waitingUsers;
public async Task JoinRoom(UserRoomConnection userRoomConnection)
{
var noOfUsers = _connections.Values.Count(x => x.Room == userRoomConnection.Room);
Expand Down Expand Up @@ -48,6 +50,11 @@ public async Task LeftRoom(UserRoomConnection userRoomConnection)
_connections.Remove(Context.ConnectionId);
await Clients.Group(userRoomConnection.Room).UserLeft(userRoomConnection, Context.ConnectionId);
}
public override Task OnConnectedAsync()
{
Clients.Caller.OnCount(_randomUsers.Count);
return base.OnConnectedAsync();
}

public override async Task OnDisconnectedAsync(Exception? exception)
{
Expand All @@ -59,6 +66,7 @@ public override async Task OnDisconnectedAsync(Exception? exception)

await base.OnDisconnectedAsync(exception);
}
await LeaveRandomRoom();
await base.OnDisconnectedAsync(exception);
}

Expand Down Expand Up @@ -104,5 +112,127 @@ public async Task ToggleAudio(string peerId, bool isAudioOn)
{
await Clients.Group(_connections[Context.ConnectionId].Room).ToggleAudio(peerId, isAudioOn);
}

public async Task JoinRandomRoom(UserDto user, VideoConfig config, string peerId)
{
if (_randomPairs.ContainsKey(Context.ConnectionId))
{
return;
}
_randomUsers.Add(Context.ConnectionId, user);
_randomPairs.Add(Context.ConnectionId, null);
await Clients.All.OnCount(_randomUsers.Count);
if (_waitingUsers.Count > 0)
{
await ConnectRandomUser(Context.ConnectionId, config, peerId);
}
else
{
if (!_waitingUsers.Contains(Context.ConnectionId))
{
_waitingUsers.Add(Context.ConnectionId);
}
}
await Clients.Client(Context.ConnectionId).JoinRoomResponse(1, 0);
}

public async Task LeaveRandomRoom()
{
if (_randomPairs.TryGetValue(Context.ConnectionId, out var randomUser))
{
if (randomUser != null)
{
if (_randomPairs.ContainsKey(randomUser))
{
_randomPairs[randomUser] = null;
}
await Clients.Client(randomUser).SkipUser();
}
}
_randomPairs.Remove(Context.ConnectionId);
_randomUsers.Remove(Context.ConnectionId);
_waitingUsers.RemoveAll((u) => u == Context.ConnectionId);
await Clients.AllExcept(Context.ConnectionId).OnCount(_randomUsers.Count);
}
public async Task SkipUser(VideoConfig config, string peerId)
{
if (_randomPairs.TryGetValue(Context.ConnectionId, out var randomUser))
{
_randomPairs[Context.ConnectionId] = null;
if (randomUser != null)
{
if (_randomPairs.ContainsKey(randomUser))
{
_randomPairs[randomUser] = null;
}
await Clients.Client(randomUser).SkipUser();
}
if (_waitingUsers.Count > 0)
{
await ConnectRandomUser(Context.ConnectionId, config, peerId);
}
else
{
if (!_waitingUsers.Contains(Context.ConnectionId))
{
_waitingUsers.Add(Context.ConnectionId);
}
}
}
}
public async Task ToggleRandomVideo(string peerId, bool isVideoOn)
{
if (_randomPairs.TryGetValue(Context.ConnectionId, out var id))
{
if (id != null)
await Clients.Client(id).ToggleVideo(peerId, isVideoOn);
}
}
public async Task ToggleRandomAudio(string peerId, bool isAudioOn)
{
if (_randomPairs.TryGetValue(Context.ConnectionId, out var id))
{
if (id != null)
await Clients.Client(id).ToggleAudio(peerId, isAudioOn);
}
}
public async Task ConnectRandomUser(string id, VideoConfig config, string peerId)
{
var user = _randomUsers.TryGetValue(id, out var value) ? value : null;
if (user == null)
{
return;
}
var randomUser = _waitingUsers.First();
_waitingUsers.RemoveAt(0);
while (!_randomUsers.ContainsKey(randomUser) || randomUser == id)
{
if (_waitingUsers.Count == 0)
{
break;
}
randomUser = _waitingUsers.First();
_waitingUsers.RemoveAt(0);
}
if (!_randomUsers.ContainsKey(randomUser))
{
return;
}
Console.WriteLine($"Connecting {user.Username} to {_randomUsers[randomUser].Username}");
_randomPairs[id] = randomUser;
_randomPairs[randomUser] = id;
await Clients.Client(randomUser).RandomUserJoined(user, config, peerId);
}
public async Task SendRandomMessage(RandomMessageDto messageDto)
{
if (_randomPairs.TryGetValue(Context.ConnectionId, out var randomUser))
{
if (randomUser != null)
{
messageDto.timeStamp = DateTime.Now;
await Clients.Client(randomUser).ReceiveRandomMessage(messageDto);
}
}
}
}
}
4 changes: 4 additions & 0 deletions Hubs/Clients/IChatClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,9 @@ public interface IChatClient
Task NewPeer(string id, UserDto user, VideoConfig config);
Task ToggleVideo(string id, bool isVideoOn);
Task ToggleAudio(string id, bool isAudioOn);
Task RandomUserJoined(UserDto user, VideoConfig config, string peerId);
Task SkipUser();
Task ReceiveRandomMessage(RandomMessageDto message);
Task OnCount(int count);
}
}
4 changes: 4 additions & 0 deletions Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using DotNetEnv.Configuration;
using Klustr_api.Data;
using Klustr_api.Dtos.Hub;
using Klustr_api.Dtos.User;
using Klustr_api.Hubs;
using Klustr_api.Interfaces;
using Klustr_api.Repository;
Expand Down Expand Up @@ -73,6 +74,9 @@
builder.Services.AddScoped<IMemberRepository, MemberRepository>();
builder.Services.AddScoped<IMessageRepository, MessageRepository>();
builder.Services.AddSingleton<IDictionary<string, UserRoomConnection>>(new Dictionary<string, UserRoomConnection>());
builder.Services.AddSingleton<IDictionary<string, string?>>(new Dictionary<string, string?>());
builder.Services.AddSingleton<IDictionary<string, UserDto>>(new Dictionary<string, UserDto>());
builder.Services.AddSingleton<List<string>>([]);
builder.Services.AddSignalR();

builder.Services.AddAuthentication(options =>
Expand Down

0 comments on commit 15948cf

Please sign in to comment.