+Semaphores for multi-threading

This commit is contained in:
Simon Martens
2025-10-01 14:59:19 +02:00
parent 9ba2a10cb8
commit d621c36437

View File

@@ -34,6 +34,7 @@ public class WebSocketMiddleware : IMiddleware {
private readonly IXMLFileProvider _xmlProvider; private readonly IXMLFileProvider _xmlProvider;
private List<WebSocket>? _openSockets; private List<WebSocket>? _openSockets;
private readonly object _socketsLock = new object();
public WebSocketMiddleware(IXMLFileProvider xmlprovider, IXMLInteractionService xmlservice, IFeatureManager featuremanager){ public WebSocketMiddleware(IXMLFileProvider xmlprovider, IXMLInteractionService xmlservice, IFeatureManager featuremanager){
this._xmlProvider = xmlprovider; this._xmlProvider = xmlprovider;
@@ -67,7 +68,9 @@ public class WebSocketMiddleware : IMiddleware {
private async Task HandleConnection(HttpContext context, WebSocket webSocket) { private async Task HandleConnection(HttpContext context, WebSocket webSocket) {
var buffer = new byte[1024 * 4]; var buffer = new byte[1024 * 4];
_openSockets!.Add(webSocket); lock (_socketsLock) {
_openSockets!.Add(webSocket);
}
WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
while (!result.CloseStatus.HasValue) { while (!result.CloseStatus.HasValue) {
var msg = Encoding.UTF8.GetString(buffer,0,result.Count); var msg = Encoding.UTF8.GetString(buffer,0,result.Count);
@@ -89,7 +92,9 @@ public class WebSocketMiddleware : IMiddleware {
} catch (WebSocketException ex) { } catch (WebSocketException ex) {
// Socket already closed // Socket already closed
} }
_openSockets!.Remove(webSocket); lock (_socketsLock) {
_openSockets!.Remove(webSocket);
}
} }
private async void _HandleFileChange(object? sender, GitState? state) { private async void _HandleFileChange(object? sender, GitState? state) {
@@ -124,16 +129,27 @@ public class WebSocketMiddleware : IMiddleware {
private async Task _SendToAll<T>(T msg) { private async Task _SendToAll<T>(T msg) {
if (_openSockets == null) return; if (_openSockets == null) return;
List<WebSocket> socketsCopy;
lock (_socketsLock) {
socketsCopy = _openSockets.ToList();
}
var socketsToRemove = new List<WebSocket>(); var socketsToRemove = new List<WebSocket>();
foreach (var socket in _openSockets.ToList()) { foreach (var socket in socketsCopy) {
try { try {
await socket.SendAsync(_SerializeToBytes(msg), WebSocketMessageType.Text, true, CancellationToken.None); await socket.SendAsync(_SerializeToBytes(msg), WebSocketMessageType.Text, true, CancellationToken.None);
} catch (WebSocketException ex) { } catch (WebSocketException ex) {
socketsToRemove.Add(socket); socketsToRemove.Add(socket);
} }
} }
foreach (var socket in socketsToRemove) {
_openSockets.Remove(socket); if (socketsToRemove.Any()) {
lock (_socketsLock) {
foreach (var socket in socketsToRemove) {
_openSockets.Remove(socket);
}
}
} }
} }