Improve performance of network worker

This commit is contained in:
Drew DeVault 2015-01-31 20:07:26 -07:00
parent ad42586170
commit ab3b6bd3b3

View File

@ -28,7 +28,8 @@ namespace TrueCraft
public IEventScheduler Scheduler { get; private set; } public IEventScheduler Scheduler { get; private set; }
public IBlockRepository BlockRepository { get; private set; } public IBlockRepository BlockRepository { get; private set; }
private Timer NetworkWorker, EnvironmentWorker; private Timer EnvironmentWorker;
private Thread NetworkWorker;
private TcpListener Listener; private TcpListener Listener;
private readonly PacketHandler[] PacketHandlers; private readonly PacketHandler[] PacketHandlers;
private IList<ILogProvider> LogProviders; private IList<ILogProvider> LogProviders;
@ -39,7 +40,7 @@ namespace TrueCraft
var reader = new PacketReader(); var reader = new PacketReader();
PacketReader = reader; PacketReader = reader;
Clients = new List<IRemoteClient>(); Clients = new List<IRemoteClient>();
NetworkWorker = new Timer(DoNetwork); NetworkWorker = new Thread(new ThreadStart(DoNetwork));
EnvironmentWorker = new Timer(DoEnvironment); EnvironmentWorker = new Timer(DoEnvironment);
PacketHandlers = new PacketHandler[0x100]; PacketHandlers = new PacketHandler[0x100];
Worlds = new List<IWorld>(); Worlds = new List<IWorld>();
@ -66,7 +67,7 @@ namespace TrueCraft
Listener.Start(); Listener.Start();
Listener.BeginAcceptTcpClient(AcceptClient, null); Listener.BeginAcceptTcpClient(AcceptClient, null);
Log(LogCategory.Notice, "Running TrueCraft server on {0}", endPoint); Log(LogCategory.Notice, "Running TrueCraft server on {0}", endPoint);
NetworkWorker.Change(100, 1000 / 20); NetworkWorker.Start();
EnvironmentWorker.Change(100, 1000 / 20); EnvironmentWorker.Change(100, 1000 / 20);
} }
@ -172,61 +173,65 @@ namespace TrueCraft
Scheduler.Update(); Scheduler.Update();
} }
private void DoNetwork(object discarded) private void DoNetwork()
{ {
if (ExecutingTick) while (true)
return; // TODO: Warn about skipped updates?
ExecutingTick = true;
for (int i = 0; i < Clients.Count && i >= 0; i++)
{ {
var client = Clients[i] as RemoteClient; bool idle = true;
var sendTimeout = DateTime.Now.AddMilliseconds(200); for (int i = 0; i < Clients.Count && i >= 0; i++)
while (client.PacketQueue.Count != 0 && DateTime.Now < sendTimeout)
{ {
IPacket packet; var client = Clients[i] as RemoteClient;
while (!client.PacketQueue.TryDequeue(out packet)) ; var sendTimeout = DateTime.Now.AddMilliseconds(200);
LogPacket(packet, false); while (client.PacketQueue.Count != 0 && DateTime.Now < sendTimeout)
PacketReader.WritePacket(client.MinecraftStream, packet);
if (packet is DisconnectPacket)
{ {
DisconnectClient(client); idle = false;
i--; IPacket packet;
break; while (!client.PacketQueue.TryDequeue(out packet)) ;
} LogPacket(packet, false);
} PacketReader.WritePacket(client.MinecraftStream, packet);
var receiveTimeout = DateTime.Now.AddMilliseconds(200); if (packet is DisconnectPacket)
while (client.DataAvailable && DateTime.Now < receiveTimeout)
{
var packet = PacketReader.ReadPacket(client.MinecraftStream);
LogPacket(packet, true);
if (PacketHandlers[packet.ID] != null)
{
try
{
PacketHandlers[packet.ID](packet, client, this);
}
catch (PlayerDisconnectException)
{ {
DisconnectClient(client); DisconnectClient(client);
i--; i--;
} break;
catch (Exception e)
{
Log(LogCategory.Debug, "Disconnecting client due to exception in network worker");
Log(LogCategory.Debug, e.ToString());
PacketReader.WritePacket(client.MinecraftStream, new DisconnectPacket("An exception has occured on the server."));
client.MinecraftStream.BaseStream.Flush();
DisconnectClient(client);
i--;
} }
} }
else var receiveTimeout = DateTime.Now.AddMilliseconds(200);
while (client.DataAvailable && DateTime.Now < receiveTimeout)
{ {
// TODO: Something productive idle = false;
var packet = PacketReader.ReadPacket(client.MinecraftStream);
LogPacket(packet, true);
if (PacketHandlers[packet.ID] != null)
{
try
{
PacketHandlers[packet.ID](packet, client, this);
}
catch (PlayerDisconnectException)
{
DisconnectClient(client);
i--;
}
catch (Exception e)
{
Log(LogCategory.Debug, "Disconnecting client due to exception in network worker");
Log(LogCategory.Debug, e.ToString());
PacketReader.WritePacket(client.MinecraftStream, new DisconnectPacket("An exception has occured on the server."));
client.MinecraftStream.BaseStream.Flush();
DisconnectClient(client);
i--;
}
}
else
{
// TODO: Something productive
}
} }
if (idle)
Thread.Sleep(100);
} }
} }
ExecutingTick = false;
} }
} }
} }