-
Notifications
You must be signed in to change notification settings - Fork 611
Description
Hi all,
I'm making a multiplayer game and using NetCoreServer as the game server web socket library. Everything has been going well, I wrapped everything in try catch and we have 20-100 players in our room at any given time and it all was running smoothly. But I got this exception that crashed the server despite it all being wrapped in try catch:
02/02/2025 17:57:20 Game WebSocket session with Id 363fd3c4-e36f-4e09-b114-41a2e7aea495 connected! 363fd3c4-e36f-4e09-b114-41a2e7aea495 Client IP Address from X-Real-IP: redacted 02/02/2025 17:57:20 Game WebSocket session with Id 363fd3c4-e36f-4e09-b114-41a2e7aea495 disconnected! Player 7526 connected. Total players: 30 Player 7526 disconnected. 02/02/2025 17:57:20 Unknown message code received: 200 from player with id: 362b3254-4a87-4dc8-974b-dc4528407b76 Full message byte array: C8-4D-6D-12-BA-BF-B8-28-17-E0-98-21-AF-BF-AD-3F-9E-A9-BB-24-BA-AF-A7-23-83-A3-BB-3E-AF-A1-AD-61-EE-87-BB-3E-AB-AB-AA-21-B7-EB-8B-1E-A6-A7-BA-3D-6C-8F-8C-4D-6F-9E-02-0C-D5-97-5D-EC-97-0C-77-95-BC-26-69-17-04-07-37-C9-A6-64-9A-15-04-C6-C8-4D-CE-64-9A-14-04-F9-96-98-CA-64-9A-17-04-C6-C8-4D-CE-64-9A-1A-04-78-34-46-25-67-89-E6-E3-F7-F8-7A-FF-FE-FD-79-F7-F1-FA-EC-9D-0C-F6-9F-70-A7 Closing session because of unknown message code. 02/02/2025 17:57:20 Game WebSocket session with Id 362b3254-4a87-4dc8-974b-dc4528407b76 disconnected! Player 7506 disconnected. 02/02/2025 17:57:20 Game WebSocket session with Id 4bd2e316-b504-4d4d-8079-2f43f817cc95 connected! 4bd2e316-b504-4d4d-8079-2f43f817cc95 Client IP Address from X-Real-IP: redacted Player 7527 connected. Total players: 29 02/02/2025 17:57:20 Game WebSocket session with Id 4bd2e316-b504-4d4d-8079-2f43f817cc95 disconnected! Player 7527 disconnected. Unhandled exception: System.ArgumentException: Invalid offset & size! (Parameter 'offset') at NetCoreServer.Buffer.ExtractString(Int64 offset, Int64 size) at NetCoreServer.HttpRequest.ReceiveHeader(Byte[] buffer, Int32 offset, Int32 size) at NetCoreServer.HttpSession.OnReceived(Byte[] buffer, Int64 offset, Int64 size) at NetCoreServer.TcpSession.ProcessReceive(SocketAsyncEventArgs e) at NetCoreServer.TcpSession.TryReceive() at NetCoreServer.TcpSession.Connect(Socket socket) at NetCoreServer.TcpServer.ProcessAccept(SocketAsyncEventArgs e) at NetCoreServer.TcpServer.ProcessAccept(SocketAsyncEventArgs e) at NetCoreServer.TcpServer.ProcessAccept(SocketAsyncEventArgs e) at NetCoreServer.TcpServer.ProcessAccept(SocketAsyncEventArgs e) at NetCoreServer.TcpServer.OnAsyncCompleted(Object sender, SocketAsyncEventArgs e) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) --- End of stack trace from previous location --- at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Net.Sockets.SocketAsyncContext.ReadOperation.System.Threading.IThreadPoolWorkItem.Execute() at System.Net.Sockets.SocketAsyncEngine.System.Threading.IThreadPoolWorkItem.Execute() at System.Threading.ThreadPoolWorkQueue.Dispatch() at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart() Unhandled exception. System.ArgumentException: Invalid offset & size! (Parameter 'offset') at NetCoreServer.Buffer.ExtractString(Int64 offset, Int64 size) at NetCoreServer.HttpRequest.ReceiveHeader(Byte[] buffer, Int32 offset, Int32 size) at NetCoreServer.HttpSession.OnReceived(Byte[] buffer, Int64 offset, Int64 size) at NetCoreServer.TcpSession.ProcessReceive(SocketAsyncEventArgs e) at NetCoreServer.TcpSession.TryReceive() at NetCoreServer.TcpSession.Connect(Socket socket) at NetCoreServer.TcpServer.ProcessAccept(SocketAsyncEventArgs e) at NetCoreServer.TcpServer.ProcessAccept(SocketAsyncEventArgs e) at NetCoreServer.TcpServer.ProcessAccept(SocketAsyncEventArgs e) at NetCoreServer.TcpServer.ProcessAccept(SocketAsyncEventArgs e) at NetCoreServer.TcpServer.OnAsyncCompleted(Object sender, SocketAsyncEventArgs e) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) --- End of stack trace from previous location --- at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Net.Sockets.SocketAsyncContext.ReadOperation.System.Threading.IThreadPoolWorkItem.Execute() at System.Net.Sockets.SocketAsyncEngine.System.Threading.IThreadPoolWorkItem.Execute() at System.Threading.ThreadPoolWorkQueue.Dispatch() at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
Here is my GameServer.cs connection methods (inherits from WsServer):
protected override void OnConnected(TcpSession session)
{
try
{
base.OnConnected(session);
}
catch (Exception e)
{
Console.WriteLine("Exception in OnConnected: " + e);
}
}
protected override void OnDisconnected(TcpSession session)
{
try
{
base.OnDisconnected(session);
}
catch (Exception e)
{
Console.WriteLine("Exception in OnDisconnected: " + e);
}
}
protected override void OnError(SocketError error)
{
Console.WriteLine($"Game WebSocket server caught an error with code {error}");
}
Here is my GameSession.cs connection methods (inherits from WsSession):
public override void OnWsConnected(HttpRequest request)
{
try
{
Console.WriteLine($"{DateTime.Now} Game WebSocket session with Id {Id} connected!");
// Get the real IP address from the headers
clientIp = null;
// Iterate over headers to find 'X-Forwarded-For' or 'X-Real-IP'
for (int i = 0; i < request.Headers; I++)
{
var header = request.Header(i);
var headerName = header.Item1;
var headerValue = header.Item2;
if (headerName.Equals("X-Forwarded-For", StringComparison.OrdinalIgnoreCase))
{
var ipAddresses = headerValue.Split(',');
clientIp = ipAddresses[0].Trim();
Console.WriteLine($"{Id} Client IP Address from X-Forwarded-For: {clientIp}");
break;
}
else if (headerName.Equals("X-Real-IP", StringComparison.OrdinalIgnoreCase))
{
clientIp = headerValue.Trim();
Console.WriteLine($"{Id} Client IP Address from X-Real-IP: {clientIp}");
break;
}
}
// If client IP is still null, use the remote endpoint
if (clientIp == null)
{
clientIp = Socket.RemoteEndPoint.ToString();
Console.WriteLine($"Client IP Address from RemoteEndPoint: {clientIp}");
}
if (clientIp != null && GameServer.IsUserBanned(clientIp))
{
Console.WriteLine($"Client IP Address {clientIp} is banned. Closing connection...");
Close(1000, "You have been banned.");
}
else
{
// Create a new player associated with this session
Player = new Player(this);
Player.LastMessageTime = DateTime.UtcNow;
GameServer.AddPlayer(Player);
// Send existing players' data to the new player
SendExistingPlayersData();
// Notify other players about the new player
BroadcastNewPlayerData();
}
}
catch (Exception e)
{
Console.WriteLine($"{DateTime.Now} Exception in OnWsConnected: {e.Message}");
}
}
public override void OnWsDisconnected()
{
Console.WriteLine($"{DateTime.Now} Game WebSocket session with Id {Id} disconnected!");
GameServer.RemovePlayer(this);
// Player removal is handled in GameServer.OnDisconnected
}
public override void OnWsReceived(byte[] buffer, long offset, long size)
{
try
{
// Ensure the buffer has at least one byte for the message code
if (size < 1)
return;
var messageCode = buffer[offset];
var messageData = new byte[size - 1];
Array.Copy(buffer, offset + 1, messageData, 0, size - 1);
Player.LastMessageTime = DateTime.UtcNow;
switch (messageCode)
{
case MessageCodes.PositionMessage:
HandlePositionMessage(messageData);
break;
Does anyone have any clue what the problem might be?
I am using NetCoreServer version 8.0.7 on .NET 8.0.405 Debian.