На моем устройстве (Win 10) и Debian мой сервис работает как положено: для каждого устройства я получаю результаты примерно за 1-3 секунды (что нормально для моего случая). Однако на другом устройстве Debian, когда я запускаю свой сервис, я блокируюсь после 10-15 устройств, и мне приходится ждать результатов 30-45 секунд (что нехорошо).
Еще немного информации: все проверяемые устройства настроены одинаково. Разница лишь в том, с какого устройства я проверяю. Все они подключены к одной локальной сети.
Код проверки ssh-устройств:
Код: Выделить всё
DeviceStatus deviceStatus = await base.CheckDevice(cancellationToken);
if (!deviceStatus.Pingable)
return deviceStatus;
using var client = CreateSshClient();
await client.ConnectAsync(cancellationToken);
string? lcdVersion = await GetLcdAppVersion(client, cancellationToken);
deviceStatus.Components.Add(new("LcdApp", true, lcdVersion));
List tasks = new();
foreach (ServiceInfo service in _options.Value.LcdServices)
tasks.Add(Task.Run(async () =>
await GetServiceInfo(deviceStatus, service, cancellationToken, client)));
await Task.WhenAll(tasks);
client.Disconnect();
return deviceStatus;
Код: Выделить всё
DeviceStatus deviceStatus = await base.CheckDevice(cancellationToken);
if (!deviceStatus.Pingable)
return deviceStatus;
bool connected = false;
string? version = null;
Stopwatch watch = new();
watch.Start();
string address = "ws://" + _device.device_ip + ":" + (_device.device_port ?? 8882) + "/api";
using var ws = new ClientWebSocket();
try
{
var timedSource = new CancellationTokenSource();
timedSource.CancelAfter(TimeSpan.FromSeconds(5));
var source = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timedSource.Token);
Task dcTask = Task.Run(async () =>
{
try
{
await Task.Delay(TimeSpan.FromSeconds(10), source.Token);
}
finally
{
if (ws.State == WebSocketState.Open)
{
_logger.LogDebug("{ip}: WebSocket timeout exceeded, disconnecting", _device.device_ip);
await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", cancellationToken);
}
if (!source.IsCancellationRequested)
source.Cancel();
}
});
await ws.ConnectAsync(new Uri(address), source.Token);
connected = ws.State == WebSocketState.Open;
if (!connected)
return deviceStatus;
var buffer = new byte[1024];
var result = await ws.ReceiveAsync(new ArraySegment(buffer), source.Token);
if (result.MessageType == WebSocketMessageType.Text)
{
var message = Encoding.UTF8.GetString(buffer, 0, result.Count);
//_logger.LogDebug("{ip}: Message received - {message}", _device.device_ip, message);
if (message.Contains("appInfo"))
{
JObject jObject = JObject.Parse(message);
AppInfo appInfo = jObject["appInfo"]!.ToObject()!;
version = appInfo.versionString;
if (version is null && appInfo.version is not null)
{
version = string.Join(".", appInfo.version);
}
}
}
await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", source.Token);
source.Cancel();
}
catch (TaskCanceledException)
{
_logger.LogInformation("{ip} is taking too long to respond", _device.device_ip);
}
catch (OperationCanceledException)
{
_logger.LogInformation("{ip} is taking too long to respond", _device.device_ip);
}
catch (Exception e)
{
if (!e.Message.Contains("close handshake"))
_logger.LogDebug("Error while checking {ip}: {e}", _device.device_ip, e.ToString());
}
deviceStatus.Components.Add(new("WebSocket", connected, version));
return deviceStatus;
Похоже, что задача отключения не работает все время, похоже, что она ожидает соединения, хотя CancellationTokenSource отменена
Я пробовал добавление задачи отключения, чтобы отменить проверку через 5 секунд. Я также оптимизировал работу с устройствами ssh, чтобы создать для каждого из них только один SshClient и запускать команды на этом одном клиенте. Он работал на первых двух (Win 10 и первом Debian), однако у другого Debian была та же проблема. Я также попробовал установить для ulimit -n значение 4096, но результат не изменился. Еще я пробовал ставить задачи в очередь, например в 5, и когда одна из них выполнена, запускаю следующую. В результате вся очередь остановилась на эти 30-45 секунд, а затем вернулась к проверке каждого устройства в ожидаемое время
Подробнее здесь: https://stackoverflow.com/questions/787 ... nsistantly