Crequency / KitX

An all-purpose toolbox app that connect everything.
https://kitx.apps.crequency.com
GNU Affero General Public License v3.0
1.17k stars 49 forks source link

[Dashboard] TcpServer high CPU usage #259

Closed Dynesshely closed 1 year ago

Dynesshely commented 1 year ago

Discussed in https://github.com/Crequency/KitX/discussions/258

经过初步检查, 初步判定并不是代码编写逻辑的问题, 而是 TcpListener.Pending 方法占用 CPU 资源过多, 相关代码如下: Network/DevicesServer.cs

    /// <summary>
    /// 接收客户端
    /// </summary>
    private static void AcceptClient()
    {
        var location = $"{nameof(DevicesServer)}.{nameof(AcceptClient)}";

        try
        {
            while (keepListen && listener is not null)
            {
                if (listener.Pending()) // <- HERE
                {
                    var client = listener.AcceptTcpClient();

                    if (client.Client.RemoteEndPoint is not IPEndPoint endpoint) continue;

                    clients.Add(endpoint.ToString(), client);

                    Log.Information($"New device connection: {endpoint}");

                    ReceiveMessage(client);
                }
            }
        }
        catch (Exception ex)
        {
            Log.Error(ex, $"In {nameof(location)}: {ex.Message}");

            Status = ServerStatus.Errored;
        }
    }

Network/PluginsServer.cs

    /// <summary>
    /// 接收客户端
    /// </summary>
    private null void AcceptClient()
    {
        var location = $"{nameof(PluginsServer)}.{nameof(AcceptClient)}";

        try
        {
            while (keepListen && listener is not null)
            {
                if (listener.Pending()) // <- HERE
                {
                    var client = listener.AcceptTcpClient();

                    if (client.Client.RemoteEndPoint is not IPEndPoint endpoint) continue;

                    clients.Add(endpoint.ToString(), client);

                    Log.Information($"New plugin connection: {endpoint}");

                    ReceiveMessage(client);
                }
            }
        }
        catch (Exception ex)
        {
            Log.Error(ex, $"In {location}: {ex.Message}");

            Status = ServerStatus.Errored;
        }
    }

占用情况如图. 基本上占用一半的资源, 另一半则是 sockets 库

image

修改建议为适当增加线程休眠时间, 如:

Thread.Sleep(500);
github-actions[bot] commented 1 year ago

Tracked by #223 .