Принцип работы коннекторов в Delphi компонентах

В моих компонентах для Delphi коннектор – это объект, осуществляющий связь с внешними объектами(объектом). Внешним объектом может выступать другая программа или другое устройство, которое поддерживает тот же интерфейс или протокол связи. В процессе связи коннектор выступает клиентом. То есть задача коннектора отправить запрос и при необходимости дождаться ответа и отправить его по обратной связи (CallBack).

TKRConnector – это базовый класс всех коннекторов. Ниже представлена схема работы коннектора

Схема работы KRConnector

Для отправки запроса используется метод Send

Задача данного метода отправить информацию о запросе в очередь на обработку. В методе Send передаются следующие параметры:

  • APack – указатель на буфер в котором находятся данные предназначенные для отправки. Если нужно получить ответ, то он сохранится в этот же буфер.
  • ALength – длинна отправляемых данных в байтах.
  • ACallBack – метод обратной связи типа TKRConnectorCallBack. Данный метод будет вызван после обработки запроса. Если нет необходимости в обратной связи, то можно передать nil.
  • AData – указатель на дополнительные данные, который будет передан в метод обратной связи (CallBack). Если есть необходимость передать дополнительную информацию о пакете, которые понадобятся в методе обратной связи, то указатель на эти данные передается в этом параметре. Если нет необходимости что-либо передавать, то устанавливаем nil.
  • AWaitResult – указывает на то, нужно ли ждать ответ на запрос. Если должен прийти ответ, но он не будет получен, то это будет считаться ошибкой ceNoResponse.
  • ARecvLen – если заранее известна длина ответа, то ее нужно указать в этом параметре. Заранее зная длину ответа коннектор будет быстрее обрабатывать входящие данные.
  • ADelimiter – разделитель или последовательность байт разделяющая входящие пакеты. Например в протоколе Modbus ASCII разделителем является последовательность #13#10 и для передачи этой последовательности нужно установить значение $0D0A в данный параметр. Если разделитель не используется, то устанавливаем ноль.
  • ADelimiterLen – длина разделителя в байтах. Если разделитель не используется, то устанавливаем ноль.

После вызова Send, информация о запросе попадает во входящую очередь коннектора, которая из себя представляет сблокированный упорядоченный список типа TKRThreadQueue. Максимальное количество запросов в очереди установлено в константе CE_QUEUE_MAX_ITEMS, а текущее количество можно узнать из свойства коннектора QueueCount. Если в момент вызова метода Send в очереди будет максимально возможное количество запросов, то будет вызван метод обратной связи с ошибкой ceQueueOverflowed.

Из входящей очереди запрос попадает в поток обработки данных типа TKRThread. Свойства коннектора WaitTime и WaitPauseTime являются настройками данного потока. Функционал потока описывается для каждого коннектора отдельно, но основные задачи во всех случаях одинаковы:

  1. Установить соединение. Если связь не установлена, то коннектор пытается подключиться с таймаутом указанным в свойстве ConnectTimeout. Если связи нет, то коннектор будет постоянно пытаться подключиться с периодом между попытками указанным в свойстве ReconnectTime. Все запросы до установки связи будут возвращать ошибку ceNotConnection.
  2. Отправить запрос. Отправка последовательности бай с таймаутом указанным в свойстве WriteTimeout. Если за указанный период данные отправить не удается, то возвращается ошибка ceDataNotSended.
  3. При необходимости дождаться ответа. Если при вызове метода Send в параметре AWaitResult передано True, то будет ожидаться ответ в течении времени указанного в свойстве WaitRespTime. Общий таймаут ожидания ответа устанавливается в свойстве ReadTimeout, но промежутки по времени между частями входящего пакета не должны превышать значение свойства WaitRespTime. То есть , фактически, если в течении времени WaitRespTime ничего не будет получено, то коннектор будет считать, что ответа нет. Если в методе Send передано значение ARecvLen больше нуля, то коннектор считает, что ответ получен, если длина полученных данных больше или ровна ARecvLen и прекращает ожидание дополнительных данных. Если ответ получить не удалось, то возвращается ошибка ceNoResponse.
  4. Результат отправить в исходящую очередь.

Исходящая очередь из себя представляет сблокированный упорядоченный список типа TKRThreadQueue. Максимальное количество запросов в очереди установлено в константе CE_QUEUE_MAX_ITEMS, а текущее количество можно узнать из свойства коннектора QueueOutCount.

Второй поток коннектора предназначен для отправки результата, то есть для вызова метода обратной связи. Свойства коннектора WaitOutTime и WaitPauseOutTime являются настройками данного потока.

Метод обратной связи представляет из себя процедуру какого либо объекта со следующими параметрами:

  • AError – ошибка типа TKRConnectorError, возникшая при обработке запроса. Если в параметре придёт ноль ceOK, то значит, что в процессе обработки запроса ошибок не возникло. Текстовые представления ошибок находятся в константе CONNECTOR_ERRORS_MSG. Также текстовое представление ошибки можно получить при помощи метода коннектора ErrorMsg.
  • APack – указатель на тот же буфер который был передан в методе Send. В этот буфер записывается ответ, поверх запроса.
  • ALength – длина ответа.
  • AData – указатель на дополнительные данные который был передан в методе коннектора Send.

В методе обратной связи нужно учитывать то, что он напрямую вызывается из исходящего потока коннектора, то есть асинхронно основному потоку.

На данный момент есть три коннектора основанные на TKRConnector:

  • KRBTConnector – беспроводная связь Bluetooth
  • KRCOMPortConnector – связь через последовательный порт
  • KRTCPConnector – сетевая связь по стеку протоколов TCP/IP

Пример использования

В приведенном ниже примере через коннектор последовательного порта опрашиваются три переменные удаленного устройства по протоколу Modbus RTU. Первая переменная будет типа Word в регистре 0, вторая типа SmallInt в регистре 1 и третья типа DWORD в регистрах 2 и 3. При корректном ответе устройства значения записываются в поля TEdit, а при ошибке в эти же поля записывается текстовое представление этих ошибок. Для синхронизации метода обратной связи с основным потоком используем оконные сообщения Windows.

Пример использование коннектора на основе класса TKRConnector
 
Поделиться:

Новости сайта

05.05.2020 15:34
Новая статья про удаленное управление принтером Domino V-series
Реализация протокола передачи данных для связи с термотрансферным принтером Domino V-series из Delphi
24.04.2020 22:14
Добавлена статья по работе с сенсором Omron FQ-CR1 из Delphi
Подключение по сети к считывателю штрих-кодов Omron FQ-CR1 из программы на Delphi
17.03.2020 20:46
Обновлен пакет компонентов для Delphi
Доступна для скачивания новая версия компонентов для Delphi, от 17.03.2020г. С данной версии библиотеки доступны и на GitHub
28.01.2020 16:15
Опубликована статья о принципе работы коннекторов в Delphi
Коннектор – это объект, осуществляющий связь с внешними объектами(объектом). Внешним объектом может выступать другая программа или другое устройство, которое поддерживает тот же интерфейс или протокол связи.

Популярные статьи

Инструкция по установке компонентов на Delphi
Подробная инструкция по установке компонентов на Delphi с видео обзором
Экспорт таблиц Google Sheets в PDF файл
Экспорт таблиц Google Sheets в PDF файл с помощью Google Script с последующим скачиванием или сохранением на Google Drive или отправкой на почту
Modbus Slave на Arduino
Реализация клиентской части протокола Modbus RTU и Modbus ASCII для контроллеров Arduino
Пример передачи данных по протоколу Modbus на Delphi
Пример передачи данных с контроллера ОВЕН ПЛК100 в программу на Delphi по протоколу Modbus