当多个客户端连接时,我的多线程在线服务器变得太慢,C#

时间:2018-07-16 23:21:01

标签: c# multithreading networking server

我正在尝试开发一个有趣的在线游戏,其中一台服务器和至少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;
        }
    }

我们非常感谢您的帮助。

0 个答案:

没有答案