Skip to content

Commit

Permalink
fix: ISingleClientProxy is not thread-safe.
Browse files Browse the repository at this point in the history
  • Loading branch information
ckeller81 committed Aug 25, 2024
1 parent 05a0a32 commit f9e4cdd
Showing 1 changed file with 13 additions and 7 deletions.
20 changes: 13 additions & 7 deletions src/TrackMate.Backend.RestApi/Hubs/TrackNodeHub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace TrackMate.Backend.RestApi.Hubs;

public class TrackNodeHub(ILogger<TrackNodeHub> logger, TrackNodeService trackNodeService, TrackService trackService) : Hub
{
private static readonly ConcurrentDictionary<string, List<ISingleClientProxy>> _trackSubscribers = new();
private static readonly ConcurrentDictionary<string, List<string>> _trackSubscribers = new();

/// <summary>
/// Creates a new <see cref="TrackNodeModel"/> to be used to create tracks.
Expand Down Expand Up @@ -46,10 +46,10 @@ public async Task<string> StartTrack(StartTrackModel startTrackModel)

_trackSubscribers.AddOrUpdate(
track.TrackId,
[ Clients.Caller ],
[ Context.ConnectionId ],
(_, list) =>
{
list.Add(Clients.Caller);
list.Add(Context.ConnectionId);
return list;
});

Expand Down Expand Up @@ -81,7 +81,7 @@ public async Task<TrackNodeModel[]> GetAllTrackNodes()
public async Task JoinTrack(string trackId)
{
logger.LogInformation("User joined track {trackId}.", trackId);
_trackSubscribers[trackId].Add(Clients.Caller);
_trackSubscribers[trackId].Add(Context.ConnectionId);
await SendToTrackAsync(trackId, "UserJoined");
}

Expand All @@ -92,7 +92,7 @@ public async Task JoinTrack(string trackId)
public async Task LeaveTrack(string trackId)
{
logger.LogInformation("User left track {trackId}.", trackId);
_trackSubscribers[trackId].Remove(Clients.Caller);
_trackSubscribers[trackId].Remove(Context.ConnectionId);
await SendToTrackAsync(trackId, "UserLeft");
}

Expand Down Expand Up @@ -134,6 +134,12 @@ private static byte[] ReadAllBytesFromStream(Stream stream)
return memoryStream.ToArray();
}

private static Task SendToTrackAsync(string trackId, string methodName, object? arg1 = null)
=> Task.WhenAll(_trackSubscribers[trackId].Select(client => client.SendAsync(methodName, arg1)));
private async Task SendToTrackAsync(string trackId, string methodName, object? arg1 = null)
{
if (_trackSubscribers.TryGetValue(trackId, out var subscribers))
{
var tasks = subscribers.Select(connectionId => Clients.Client(connectionId).SendAsync(methodName, arg1));
await Task.WhenAll(tasks);
}
}
}

0 comments on commit f9e4cdd

Please sign in to comment.