Корректное отключение клиента по таймауту

Стартовая страница Форумы Разработка и интеграция Корректное отключение клиента по таймауту

Помечено: 

Просмотр 11 сообщений - с 1 по 11 (из 11 всего)
  • Автор
    Сообщения
  • #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();
    }

    #34416
    Evgeniy58
    Участник

    DrvTester вываливает такое же исключение, если не было данных в течении 60 сек.

    #34449
    Mikhail
    Модератор

    Если TCP-сервер разрывает соединение, или отваливается связь, то TCP-клиент никак этого не замечает. Поэтому необходимо на устройстве обрабатывать ошибки при попытке отправить новую порцию данных. Если этого сделать не удалось с заданного количества попыток, то нужно переподключиться.

    #34450
    Mikhail
    Модератор

    Что является мастером в данном случает, то есть какая сторона отправляет запрос на получение данных?

    #34460
    Evgeniy58
    Участник

    Мастером является RAPIDSCADA. Но запросы слать не планируется. Скада открывает соединение, к ней подключается клиент (устройство мониторинга температуры) и раз в три секунды шлет текущие значения, без запросов. В принципе всё работает, меня только беспокоит ситуация когда GPRS устройство отключилось(некорректно) в Журнале сообщений выскакивает
    Scada.ScadaException: Ошибка при считывании данных: Cannot access a disposed object.
    В приницпе и с этим Exception, всё достаточно стабильно работает. Думал что есть какой-то вариант чекать соединение на актуальность и отключать клиента по таймауту.

    #34461
    manjey73
    Участник

    Ну если со стороны клиента есть проверка подключения, так и поступите, при данном Exception просто закрывайте сокет, а клиент когда выйдет на связь снова его откроет.

    з.ы. тут наверное надо понять, где этот Exception возникает, чтобы в коде вставить заглушку по закрытию сокета.

    #34465
    JurasskPark
    Участник

    Подушню. Почему это мастер скада, если она принимает сигналы и является клиентом? ?
    Или я всё забыл или уже давно ничего не понимаю. Но всегда кто инициализировал данные, запросы был мастером.
    Поэтому в данном случае скада — клиент.
    Закончил душнить.

    #34466
    Evgeniy58
    Участник

    Под мастером я имел ввиду тип канала связи TCP-сервер

    Behavior = Master
    ClientLifetime = 60
    ConnectionMode = Shared
    DeviceMapping = ByIPAddress
    TcpPort = 10502

    https://postimg.cc/phz89fM4

    #34470
    manjey73
    Участник

    А, тогда вы вряд ли что поменяете сами. Это только к коде разработчик может.
    Хотя исходники есть, можете поймать где это исключение, добавить подобную штуку и отослать Михаилу. А он посмотрит и может добавит, окультурив.

    #34492
    Mikhail
    Модератор
    2024-08-29 15:57:39 Сеанс связи с устройством [4] Э-001
    Приём (0/300):
    Ошибка связи
    

    Под мастером я понимаю ту сторону, которая отправляет запрос и ждёт ответа. При этом мастер может быть как TCP-клиентом, так и TCP-сервером.
    Но из журнала выше не видно, что Коммуникатор является мастером. Похоже, что он клиент.

    Ошибка не слишком красивая, но сначала нужно выяснить более точно, кто ведущий/ведомый, сервер/клиент.

    #34493
    Mikhail
    Модератор

    На скриншоте видно, что используется канал связи типа TCP-сервер, и Коммуникатор является мастером.
    Какой драйвер используется для опроса устройств?

Просмотр 11 сообщений - с 1 по 11 (из 11 всего)
  • Для ответа в этой теме необходимо авторизоваться.