Improve WS Handling

This commit is contained in:
Archangel
2025-02-17 18:44:58 +01:00
parent 054074c51f
commit 651743ee96
2 changed files with 31 additions and 26 deletions
+29 -23
View File
@@ -1,4 +1,5 @@
using System.Net.WebSockets;
using System;
using System.Net.WebSockets;
using Core.Models.Utils;
using Core.Servers.Ws;
using SptCommon.Annotations;
@@ -23,9 +24,12 @@ public class WebSocketServer(
.Where(wsh => context.Request.Path.Value.Contains(wsh.GetHookUrl()))
.ToList();
var cts = new CancellationTokenSource();
var wsToken = cts.Token;
if (socketHandlers.Count == 0)
{
var message = $"Socket connection received for url {context.Request.Path.Value}, but there is not websocket handler configured for it";
var message = $"Socket connection received for url {context.Request.Path.Value}, but there is no websocket handler configured for it!";
await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, message, CancellationToken.None);
return;
}
@@ -40,36 +44,38 @@ public class WebSocketServer(
await wsh.OnConnection(webSocket, context);
}
var messageBuffer = new byte[1024];
try
// Discard this task, we dont need to await it.
_ = Task.Run(async () =>
{
while (webSocket.State == WebSocketState.Open)
while (!wsToken.IsCancellationRequested)
{
var receiveResult = await webSocket.ReceiveAsync(new ArraySegment<byte>(messageBuffer), CancellationToken.None);
if (receiveResult.MessageType == WebSocketMessageType.Text || receiveResult.MessageType == WebSocketMessageType.Binary)
var messageBuffer = new byte[1024 * 4];
var isEndOfMessage = false;
while (!isEndOfMessage)
{
foreach (var wsh in socketHandlers)
{
await wsh.OnMessage(messageBuffer.ToArray(), receiveResult.MessageType, webSocket, context);
}
var buffer = new ArraySegment<byte>(messageBuffer);
var readTask = await webSocket.ReceiveAsync(buffer, wsToken);
isEndOfMessage = readTask.EndOfMessage;
}
else if (receiveResult.MessageType == WebSocketMessageType.Close)
foreach (var wsh in socketHandlers)
{
foreach (var wsh in socketHandlers)
{
await wsh.OnClose(webSocket, context);
}
await wsh.OnMessage(messageBuffer.ToArray(), WebSocketMessageType.Text, webSocket, context);
}
}
}, wsToken);
while (webSocket.State == WebSocketState.Open)
{
// Keep this thread sleeping unless this status changes.
Thread.Sleep(1000);
}
catch (Exception)
foreach (var wsh in socketHandlers)
{
foreach (var wsh in socketHandlers)
{
await wsh.OnClose(webSocket, context);
}
await cts.CancelAsync();
await wsh.OnClose(webSocket, context);
}
}
}
@@ -77,8 +77,6 @@ public class SptWebSocketConnectionHandler(
var playerInfoText = $"{playerProfile.ProfileInfo.Username} ({sessionID})";
_logger.Info($"[ws] player: {playerInfoText} has disconnected");
}
await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "Client closed connection", CancellationToken.None);
}
public void SendMessage(string sessionID, WsNotificationEvent output)
@@ -111,7 +109,8 @@ public class SptWebSocketConnectionHandler(
}
catch (Exception err)
{
_logger.Error(_localisationService.GetText("websocket-message_send_failed_with_error", err));
_logger.Error(_localisationService.GetText("websocket-message_send_failed_with_error"), err);
Console.WriteLine(err);
}
}