我正在尝试开发一个有趣的在线游戏,其中一台服务器和至少2个客户端在一个“房间”中玩。我的逻辑如下:首先让服务器等待客户端连接,在客户端连接到服务器后,我为此客户端创建一个线程(以便客户端可以在与主屏幕交互时向服务器发送消息)。此后,如果客户想要玩游戏,则单击“开始比赛”按钮,如果另一个客户也这样做,则两个客户都进入另一个线程以仅在他们之间玩游戏。因此,我为每个连接的客户端创建了一个线程,并为要播放的每2个客户端创建了一个线程。 现在,当我有2个玩家在玩游戏时,一切都会顺利进行,问题是当另外2个玩家想要玩游戏时,服务器独立服务器停止响应(但是您仍然可以连接到服务器并发送消息),并且游戏变得非常慢我正在尝试了解多线程,这就是为什么我正在做这个项目,所以也许我错过了一些东西。我应该为每个客户端仅创建2个线程(当它们实际上在游戏中时,如果不是只有1个),并且有4个客户端的最大线程数是8,那么为什么我的服务器变得如此缓慢和崩溃?
这是我接受客户的地方:
private void AcceptTcpClient(IAsyncResult ar)
{
TcpListener listener = (TcpListener)ar.AsyncState;
ServerClient sc = new ServerClient(listener.EndAcceptTcpClient(ar));
sc.SetisInGame(false); // not in game, just in the main menu
clients.Add(sc);
new Thread(() => MainPanelRoomThread(sc)).Start();
StartListening();
}
当客户端连接时,这是我的主题:
private void MainPanelRoomThread(ServerClient scThread)
{
while (true)
{
if (!serverStarted)
return;
if (!scThread.GetisInGame()) //check if its not in game so it can receive data
{
NetworkStream stream = scThread.tcp.GetStream();
if (stream.DataAvailable)
{
StreamReader streamReader = new StreamReader(stream, true);
string data = streamReader.ReadLine();
if (data != null)
OnIncomingData(scThread, data); // waiting for that from the client
}
}
}
}
在OnIncomingData函数中,我等待一条消息,提示客户想要进入游戏,以便我可以启动另一个线程:
private void OnIncomingData(ServerClient c, string data)
{
Debug.Log("Server = " + data);
string[] aData = data.Split('|');
switch (aData[0])
{
case "CMATCH":
if (aData[1].Contains("true"))
{
queueClients.Enqueue(c);
if (queueClients.Count == 2)
new Thread(new ThreadStart(RoomThread)).Start(); //start the Game only if 2 players are waiting for the game to start.
else
BroadCast("SMATCH|false", c);
}else if (aData[1].Contains("false"))
{
queueClients.Dequeue();
BroadCast("SMATCH|true", c);
}
break;
}
}
最后进入游戏室:
private void RoomThread()
{
string msg = "";
List<ServerClient> players = new List<ServerClient>();
List<ServerClient> disconnected = new List<ServerClient>();
int tamanoCola = queueClients.Count;
for(int i = 0; i < tamanoCola; i++)
{
players.Add(queueClients.Dequeue());
msg = players[i].clientName + "|";
players[i].isMainPlayer = (i == 0);
players[i].SetisInGame(true); //its in game
BroadCast("SWHO|" + msg + ((players[i].isMainPlayer) ? 1 : 0).ToString(), players[i]);
}
while (true)
{
if (!serverStarted)
return;
foreach (ServerClient c in players)
{
//check if client is still playing (either because the connection died or someone won)
if (!IsConnected(c.tcp))
{
c.tcp.Close();
disconnected.Add(c);
continue;
}
else
{
NetworkStream stream = c.tcp.GetStream();
if (stream.DataAvailable)
{
StreamReader streamReader = new StreamReader(stream, true);
string data = streamReader.ReadLine();
if (data != null)
OnIncomingData(c, data, players);
}
}
}
if (disconnected.Count >= 1)
return;
}
}
我们非常感谢您的帮助。