Канал связи TCP-сервер

Помечено: 

Просмотр 13 сообщений - с 1 по 13 (из 13 всего)
  • Автор
    Записи
  • #7449
    Crouli
    Участник

    Здравствуйте.
    Подскажите как работает линия связи с Каналом связи TCP-сервер (поведение master, соединение индивидуальное, выбор КП определяется DLL)
    При одновременном подключении 10 клиентов они опрашиваются параллельно (создаются несколько потоков) или они опрашиваются последовательно (в одном потоке)?

    Возможно ли реализовать такой опрос: клиенты подключаются к серверу и остаются на связи пока сами не разорвут соединение, при этом опрашиваются параллельно в разных потоках?

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

    Добрый день!

    Если поведение Мастер — то сервер сам запрашивает данные. На одну линию связи — один поток.
    Поведение Слейв — сервер обрабатывает данные по мере их поступления от устройств.

    Вы уже выбрали устройства, которые будут использоваться в системе, ещё выбираете или разрабатываете сами?

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

    «выбор КП определяется DLL» работает для тех драйверов, которые поддерживают этот режим.

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

    Возможно ли реализовать такой опрос: клиенты подключаются к серверу и остаются на связи пока сами не разорвут соединение, при этом опрашиваются параллельно в разных потоках?

    На одной линии связи один поток. Если нужно опрашивать параллельно в режиме Мастер, то потребуется создать несколько линий связи.

    #7458
    Crouli
    Участник

    Спасибо за ответ
    У нас написан драйвер для получения данные по Modbus TCP в slave режиме (ПЛК подключается к TCP серверу и начинает записывать регистры). Это как KpModbus.dll только работающий в режиме слейв. Привязка идет при первом полученном регистре по адресу устройства.
    НО поведение TCP сервера стоит мастер, если поставить слейв для каждого соединения будет создаваться свой поток?

    #7460
    Crouli
    Участник

    Попробовал установить поведение TCP сервера слейв в логах
    ———————————————————————————
    2017-10-03 15:59:48 Инициализация линии связи 16 «TcpПорт(0.70Tcp5028)<-Плк304(НолинскКот)»
    2017-10-03 15:59:48 Ошибка при инициализации канала связи: Поведение Slave канала связи не поддерживается КП 58 «Нолинск Котельная №11».

    Есть ли пример драйвера работающего в режиме слейв?

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

    Такой драйвер не в общем доступе. Вам нужно добавить следующее в логику драйвера:

    /// 
    /// Проверить поддержку режима работы канала связи
    /// 
    public override bool CheckBehaviorSupport(CommChannelLogic.OperatingBehaviors behavior)
    {
        return behavior == CommChannelLogic.OperatingBehaviors.Slave;
    }
    
    #7465
    Mikhail
    Модератор
    /// 
    /// Обработать не считанный входящий запрос, относящийся к произвольному КП на линии связи
    /// 
    public override bool ProcUnreadIncomingReq(Connection conn, ref KPLogic targetKP)
    {
        base.ProcUnreadIncomingReq(conn, ref targetKP);
    ...
    
    #7466
    Mikhail
    Модератор

    если поставить слейв для каждого соединения будет создаваться свой поток?

    Точно не знаю, как .NET реализует входящие TCP подключения, но по поведению будет асинхронно.

    #7467
    Mikhail
    Модератор
    /// <summary>
    /// Выполнить сеанс опроса КП
    /// </summary>
    public override void Session()
    {
      // пустой метод для слейва
    }
    
    #7482
    Crouli
    Участник

    Добрый день. Изменил драйвер. Опрос и привязку необходимо делать в ProcUnreadIncomingReq?

    
    public override bool ProcUnreadIncomingReq(Connection conn, ref KPLogic targetKP)
            {
                if (targetKP == null)
                {
                    //привязка кп
                    targetKP = CommLineSvc.FindKPLogic(-1, a_MBAP_device_address.ToString());
                }
                else
                {
    //.... чтение данных ..... 
                        for (int i = 0; i < g_modbus_slave.g_Elems.Elems.Count; i++)
                        {
                            if (g_modbus_slave.g_Elems.GetElemValNeedUpdateAndSetFalse(i))
                            {
                                SetCurData(i, g_modbus_slave.g_Elems.GetElemVal(i), 1);
                            }
                        }
                    }
    
                }           
    
                return base.ProcUnreadIncomingReq(conn, ref targetKP);;
            }
    

    В текущей реализации если у одного из КП поставить большой таймаут и он не ответит то другие КП не будут опрашиваться на время этого таймаута. Еще пробовал создавать бесконечный пустой цикл для одного из КП в ProcUnreadIncomingReq

                       while (Number == 58)
                        { 
                       
                        }
    

    после подключения и идентификации этого КП перестают опрашиваться все

    • Ответ изменён 8 лет, 10 месяцев назад пользователем Crouli.
    • Ответ изменён 8 лет, 10 месяцев назад пользователем Crouli.
    • Ответ изменён 8 лет, 10 месяцев назад пользователем Crouli.
    • Ответ изменён 8 лет, 10 месяцев назад пользователем Crouli.
    #7499
    Mikhail
    Модератор

    Опрос и привязку необходимо делать в ProcUnreadIncomingReq?

    Да.
    Я делал так в этом методе:

                    if (targetKP == null)
                        targetKP = CommLineSvc.FindKPLogic(headerData.DevID, null);
    
                    if (targetKP == null)
                    {
                        WriteToLog(string.Format(
                            "Ошибка: КП с адресом {0} не найден", headerData.DevID));
                    }
                    else if (targetKP.Address != headerData.DevID)
                    {
                        WriteToLog(string.Format(
                            "Ошибка: ожидалось сообщение от контроллера {0}", targetKP.Address));
                    }
    
    #7501
    Mikhail
    Модератор

    base.ProcUnreadIncomingReq(conn, ref targetKP); — лучше поставьте в самое начало метода

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