broadcast

This commit is contained in:
Stef Heyenrath
2026-02-22 19:12:03 +01:00
parent 0782dc3998
commit 8287ae79ec
6 changed files with 530 additions and 22 deletions
@@ -3,6 +3,7 @@
using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using System.Net.WebSockets;
using static System.Net.Mime.MediaTypeNames;
namespace WireMock.WebSockets;
@@ -48,12 +49,24 @@ internal class WebSocketConnectionRegistry
/// <summary>
/// Broadcast text to all connections
/// </summary>
public async Task BroadcastTextAsync(string text, CancellationToken cancellationToken = default)
public async Task BroadcastAsync(string text, Guid? excludeConnectionId, CancellationToken cancellationToken = default)
{
var tasks = _connections.Values
.Where(c => c.WebSocket.State == WebSocketState.Open)
.Select(c => c.SendAsync(text, cancellationToken));
var tasks = Filter(excludeConnectionId).Select(c => c.SendAsync(text, cancellationToken));
await Task.WhenAll(tasks);
}
/// <summary>
/// Broadcast binary to all connections
/// </summary>
public async Task BroadcastAsync(byte[] bytes, Guid? excludeConnectionId, CancellationToken cancellationToken = default)
{
var tasks = Filter(excludeConnectionId).Select(c => c.SendAsync(bytes, cancellationToken));
await Task.WhenAll(tasks);
}
private IEnumerable<WireMockWebSocketContext> Filter(Guid? excludeConnectionId)
{
return _connections.Values
.Where(c =>c.WebSocket.State == WebSocketState.Open && (!excludeConnectionId.HasValue || c.ConnectionId != excludeConnectionId));
}
}
@@ -94,19 +94,30 @@ public class WireMockWebSocketContext : IWebSocketContext
}
/// <inheritdoc />
public async Task CloseAsync(WebSocketCloseStatus closeStatus, string statusDescription)
public async Task CloseAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken = default)
{
await WebSocket.CloseAsync(closeStatus, statusDescription, CancellationToken.None);
await WebSocket.CloseAsync(closeStatus, statusDescription, cancellationToken);
LogWebSocketMessage(WebSocketMessageDirection.Send, WebSocketMessageType.Close, $"CloseStatus: {closeStatus}, Description: {statusDescription}", null);
}
/// <inheritdoc />
public async Task BroadcastTextAsync(string text, CancellationToken cancellationToken = default)
public async Task BroadcastAsync(string text, bool excludeSender = false, CancellationToken cancellationToken = default)
{
if (Registry != null)
{
await Registry.BroadcastTextAsync(text, cancellationToken);
Guid? excludeConnectionId = excludeSender ? ConnectionId : null;
await Registry.BroadcastAsync(text, excludeConnectionId, cancellationToken);
}
}
/// <inheritdoc />
public async Task BroadcastAsync(byte[] bytes, bool excludeSender = false, CancellationToken cancellationToken = default)
{
if (Registry != null)
{
Guid? excludeConnectionId = excludeSender ? ConnectionId : null;
await Registry.BroadcastAsync(bytes, excludeConnectionId, cancellationToken);
}
}