Стартовая страница › Форумы › Разработка и интеграция › Корректное отключение клиента по таймауту
Помечено: драйвер
- В этой теме 10 ответов, 4 участника, последнее обновление 1 год, 9 месяцев назад сделано
Mikhail.
-
АвторСообщения
-
29.08.2024 в 16:31 #34415
Evgeniy58
УчастникВсем привет, возникла необходимость реализовать собственный драйвер под устройство. Устройство подключается к TCP-серверу(Rapidscada) по GPRS каналу и шлет текущие данные. Но при отключении или потери связи корректно не отключается от сервера.
2024-08-29 15:57:32 Сеанс связи с устройством [4] Э-001
Приём (0/300):
Ошибка связи
Приём (0/300):
Ошибка связи
Приём (0/300):
Ошибка связи
Сеанс опроса драйвера DrvEs:
Получено за 6183 мс2024-08-29 15:57:39 Сеанс связи с устройством [4] Э-001
Приём (0/300):
Ошибка связи
2024-08-29 15:57:41 Отключение клиента 192.168.101.100
2024-08-29 15:57:41 Ошибка при вызове метода Session устройства [4] Э-001:
Scada.ScadaException: Ошибка при считывании данных: Cannot access a disposed object.
Object name: ‘System.Net.Sockets.NetworkStream’.
—> System.ObjectDisposedException: Cannot access a disposed object.
Object name: ‘System.Net.Sockets.NetworkStream’.
at Scada.Comm.Drivers.DrvCnlBasic.Logic.TcpConnection.Read(Byte[] buffer, Int32 offset, Int32 count, Int32 timeout, ProtocolFormat format, String& logText)
— End of inner exception stack trace —
at Scada.Comm.Drivers.DrvCnlBasic.Logic.TcpConnection.Read(Byte[] buffer, Int32 offset, Int32 count, Int32 timeout, ProtocolFormat format, String& logText)
at Scada.Comm.Drivers.DrvEs.Logic.DevEsLogic.Session()
at Scada.Comm.Engine.DeviceWrapper.Session()2024-08-29 15:57:41 Невозможно выполнить сеанс связи с устройством [4] Э-001, т.к. соединение не установлено
2024-08-29 15:58:08 Соединение с клиентом 192.168.101.100Подскажите в какую сторону копать, чтобы корректно обработать таймаут неактивности соединения, по отсутствию полученных данных. Буду благодарен за любые наводки.
Метод Session() реализовал по подобию открытых драйверов на github.
public override void Session()
{
base.Session();
Stopwatch stopwatch = Stopwatch.StartNew();int tryNum = 0;
if (LastRequestOK)
{
LastRequestOK = false;while (RequestNeeded(ref tryNum)) // Использует количество попыток запроса при ошибке из настроек Опроса Устройства
{
string logText;
readcnt = Connection.Read(inBuf, 0, inBuf.Length, PollingOptions.Timeout, ProtocolFormat.Hex, out logText);
Log.WriteLine(logText);
if (readcnt == 0)
{
LastRequestOK = false;
Log.WriteLine(CommPhrases.ResponseError); // Нет ответа по Timeout — Ошибка связи!
}
else
{
Log.WriteLine(CommPhrases.ResponseOK);
LastRequestOK = true;
}
FinishRequest();
tryNum++;
}
}
stopwatch.Stop();
Log.WriteLine(«Сеанс опроса драйвера DrvEs:»);
Log.WriteLine(Locale.IsRussian ?
«Получено за {0} мс» :
«Received in {0} ms», stopwatch.ElapsedMilliseconds);FinishSession();
}29.08.2024 в 16:32 #34416Evgeniy58
УчастникDrvTester вываливает такое же исключение, если не было данных в течении 60 сек.
30.08.2024 в 15:11 #34449
MikhailМодераторЕсли TCP-сервер разрывает соединение, или отваливается связь, то TCP-клиент никак этого не замечает. Поэтому необходимо на устройстве обрабатывать ошибки при попытке отправить новую порцию данных. Если этого сделать не удалось с заданного количества попыток, то нужно переподключиться.
30.08.2024 в 15:13 #34450
MikhailМодераторЧто является мастером в данном случает, то есть какая сторона отправляет запрос на получение данных?
30.08.2024 в 15:29 #34460Evgeniy58
УчастникМастером является RAPIDSCADA. Но запросы слать не планируется. Скада открывает соединение, к ней подключается клиент (устройство мониторинга температуры) и раз в три секунды шлет текущие значения, без запросов. В принципе всё работает, меня только беспокоит ситуация когда GPRS устройство отключилось(некорректно) в Журнале сообщений выскакивает
Scada.ScadaException: Ошибка при считывании данных: Cannot access a disposed object.
В приницпе и с этим Exception, всё достаточно стабильно работает. Думал что есть какой-то вариант чекать соединение на актуальность и отключать клиента по таймауту.30.08.2024 в 15:32 #34461
manjey73УчастникНу если со стороны клиента есть проверка подключения, так и поступите, при данном Exception просто закрывайте сокет, а клиент когда выйдет на связь снова его откроет.
з.ы. тут наверное надо понять, где этот Exception возникает, чтобы в коде вставить заглушку по закрытию сокета.
30.08.2024 в 18:48 #34465
JurasskParkУчастникПодушню. Почему это мастер скада, если она принимает сигналы и является клиентом? ?
Или я всё забыл или уже давно ничего не понимаю. Но всегда кто инициализировал данные, запросы был мастером.
Поэтому в данном случае скада — клиент.
Закончил душнить.30.08.2024 в 19:04 #34466Evgeniy58
УчастникПод мастером я имел ввиду тип канала связи TCP-сервер
Behavior = Master
ClientLifetime = 60
ConnectionMode = Shared
DeviceMapping = ByIPAddress
TcpPort = 1050230.08.2024 в 19:15 #34470
manjey73УчастникА, тогда вы вряд ли что поменяете сами. Это только к коде разработчик может.
Хотя исходники есть, можете поймать где это исключение, добавить подобную штуку и отослать Михаилу. А он посмотрит и может добавит, окультурив.02.09.2024 в 12:35 #34492
MikhailМодератор2024-08-29 15:57:39 Сеанс связи с устройством [4] Э-001 Приём (0/300): Ошибка связи
Под мастером я понимаю ту сторону, которая отправляет запрос и ждёт ответа. При этом мастер может быть как TCP-клиентом, так и TCP-сервером.
Но из журнала выше не видно, что Коммуникатор является мастером. Похоже, что он клиент.Ошибка не слишком красивая, но сначала нужно выяснить более точно, кто ведущий/ведомый, сервер/клиент.
02.09.2024 в 12:37 #34493
MikhailМодераторНа скриншоте видно, что используется канал связи типа TCP-сервер, и Коммуникатор является мастером.
Какой драйвер используется для опроса устройств? -
АвторСообщения
- Для ответа в этой теме необходимо авторизоваться.