Performance: frame broadcasts once, Socket.Select instead of fixed sleep, reuse message list

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-27 15:03:51 +02:00
co-authored by Claude Opus 5.5
parent 6f8474d66b
commit 3b17baf739
2 changed files with 37 additions and 8 deletions
+20 -2
View File
@@ -154,7 +154,7 @@ public sealed class GameServer
PollClients();
RunCommands();
Timers();
Thread.Sleep(2);
WaitForTraffic();
}
foreach (var c in clients.Values)
@@ -672,8 +672,26 @@ public sealed class GameServer
void Broadcast(MsgType type, byte[] payload, int except = -1)
{
byte[] frame = null; // nur einmal rahmen, nicht pro Spieler
foreach (var c in clients.Values)
if (c.Id != except && c.State == ClientState.Joined) c.Conn.Send(type, payload);
if (c.Id != except && c.State == ClientState.Joined) c.Conn.SendFrame(frame ??= Wire.Frame(type, payload));
}
readonly List<Socket> waitList = new();
/// <summary>
/// Bis zu ein paar Millisekunden warten, aber sofort weitermachen, sobald ein Spieler etwas schickt oder jemand
/// verbinden will - schneller als festes Schlafen und ohne Leerlauf-Last.
/// </summary>
void WaitForTraffic()
{
waitList.Clear();
waitList.Add(listener.Server);
foreach (var c in clients.Values)
if (!c.Conn.IsClosed) waitList.Add(c.Conn.Socket);
int micros = clients.Count == 0 ? 50_000 : 5_000; // leerer Server: seltener aufwachen
try { Socket.Select(waitList, null, null, micros); }
catch { Thread.Sleep(2); } // z.B. Socket wurde gerade geschlossen
}
// ---------------------------------------------------------------- Konsole