// Copyright © WireMock.Net using System.Collections.Concurrent; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Net.WebSockets; namespace WireMock.WebSockets; /// /// Registry for managing WebSocket connections per mapping /// internal class WebSocketConnectionRegistry { private readonly ConcurrentDictionary _connections = new(); /// /// Add a connection to the registry /// public void AddConnection(WireMockWebSocketContext context) { _connections.TryAdd(context.ConnectionId, context); } /// /// Remove a connection from the registry /// public void RemoveConnection(Guid connectionId) { _connections.TryRemove(connectionId, out _); } /// /// Get all connections /// public IReadOnlyCollection GetConnections() { return _connections.Values.ToList(); } /// /// Try to get a specific connection /// public bool TryGetConnection(Guid connectionId, [NotNullWhen(true)] out WireMockWebSocketContext? connection) { return _connections.TryGetValue(connectionId, out connection); } /// /// Broadcast text to all connections /// public async Task BroadcastTextAsync(string text, CancellationToken cancellationToken = default) { var tasks = _connections.Values .Where(c => c.WebSocket.State == WebSocketState.Open) .Select(c => c.SendAsync(text, cancellationToken)); await Task.WhenAll(tasks); } }