Протокол связи AggreGate

Протокол связи AggreGate - это открытый, безопасный и хорошо документированный протокол, используемый для связи между серверами, агентами и веб-/десктоп-клиентами AggreGate. Связь осуществляется по одиночному TCP-соединению, которое может быть дополнительно защищено шифрованием SSL/TLS.

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

Существует несколько открытых реализаций AggreGate Протокола, включая Java и Android Java, .NET и .NET Compact, C/C++, Tibbo BASIC и т.д.

Обзор протокола

В рамках сеанса связи обе стороны обмениваются командами. Отправитель команд называется клиентом, а другая сторона - сервером:

  • При обмене данными между AggreGate Server и AggreGate Client инициатором (клиентом) является AggreGate Client.

  • При обмене данными между AggreGate Server и AggreGate Агентом, инициатором (клиентом) является AggreGate Server.

  • В распределенной архитектуре инициатор команды (клиент) является потребителем, а поставщик выступает в роли сервера.

В настоящее время существует две современные версии протокола: 2 и 3. Различия между версиями описаны в каждом параграфе статьи документации.

Инкапсуляция команд

Команды инкапсулируются с помощью символов <STX> (0x02) и <CR> (0x0D). Команды извлекаются из потока данных, а все остальные данные отбрасываются. Другие аспекты зависят от версии протокола.

Версия 2

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

<STX> команда<CR>

Если имеется два или более символов <STX> без <CR>, все данные, относящиеся к текущему, отбрасываются в каждом полученном <STX>:

<STX>aaa<STX>bbb<CR> - рассматривается как команда bbb.

Версия 3

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

<STX><L1><L2><L3><L4><T>команда<CR>.

После символа <STX> следует 4-байтовое целое число: <L1><L2><L3><L4>. Это длина команды в байтах.

Далее следует командный байт типа <T>. В этой версии протокола команда может быть одного из двух типов: Raw (0) и Compressed(1). Raw означает, что команда отправляется в виде массива символов. Compressed означает, что команда отправляется в сжатом виде в виде массива байтов ZLIB.

Затем команда проходит в первичном или сжатом состоянии, инкапсуляция закрывается, используя символ <CR>.

Пример инкапсуляции команды для версии протокола №3: <STX><0><0><0><7><0>R/123/A<CR>

Структура команды

Каждая команда состоит из нескольких частей, разделенных символами 0x17 ("Разделитель команд"). В данном руководстве символ-разделитель команд обозначен символом /. Например:

<STX>aaa/bbb/ccc<CR>

Содержит три части: aaa, bbb и ccc.

Таким образом, три символа зарезервированы и не могут появляться внутри частей команды:

Код символа

Название:

0x02

STX

0x0D

CR

0x17

ETB

Каждая команда имеет следующую структуру:

<STX> код_команды/параметры_команды...<CR>

command_code - это отдельный символ, один из:

M

Команда "Сообщение"

R

Команда "Ответ"

command_parameters - один или несколько параметров, относящихся к коду команды и разделенных символом /.

Команды

Команда "message"

Структура этой команды выглядит следующим образом (начиная с этого момента, первый символ <STX> и оконечный <CR> не указываются):

M/message_ID/message_code/message_parameters...

message_ID уникален в пределах текущей сессии.

message_code - символ, указывающий на тип сообщения. Доступность кодов сообщений:

S

Сообщение "Start"

O

Сообщение "Operation"

E

сообщение "Event"

message_parameters - один или несколько параметров, специфичных для кода сообщения, разделенных символом /.

Команда "reply"

R/reply_ID/reply_code/reply_parameters...

reply_ID должен быть равен идентификатору сообщения, на которое отвечает.

Параметрreply_code - символ, указывающий тип ответа. Доступность кодов ответа:

A

Успешно (за ним может следовать необязательный параметр data_table, см. раздел кодирование таблиц данных)

D

Отказ в доступе

E

Ошибка (может сопровождаться одним или двумя параметрами: сообщением об ошибке и/или строкой подробностей ошибки в кодировке передачи)

L

Учетная запись пользователя временно заблокирована из-за нарушения ограничений безопасности

M

Операция запрещена, так как сервер находится в режиме обслуживания

Сообщения

Сообщение "start"

M/message_ID/S/protocol_version

Формат этого сообщения гарантированно останется неизменным в будущем. Оно должно быть отправлено клиентом в качестве самой первой команды при обмене данными с сервером. Сервер возвращает ошибку, если до отправки сообщения Start было отправлено любое другое сообщение.

protocol_version - целое число, указывающее на версию протокола связи, поддерживаемую клиентом. В настоящее время используется версия 3.

Сервер отвечает на команду Start командой Reply. Если версия протокола, указанная клиентом, поддерживается сервером, то код ответа будет Success, в противном случае - Доступ запрещен. Дополнительную информацию см. в описании команды Reply.

Сообщение "operation"

M/message_ID/O/operation/context_name/entity[/data_table]

Команда operation приказывает серверу выполнить операцию над заданным контекстом.

Operation- это свойство, определяющее операцию, которая должна быть выполнена. context_name - это имя контекста, для которого выполняется запрашиваемая операция. entity- это параметр, специфичный для операции. Это может быть имя переменной, если операция называется "Set variable", или имя функции, если операция называется "Call function".

Список доступных кодов операций:

G

Операция получения переменной

S

Использовать операцию установки переменной

C

Вызов функции

L

Добавить операцию слушателя событий

R

Удалить операцию слушателя событий

data_table - необязательный параметр, содержащий специфические для операции данные. Подробности см. в приложении " кодирование таблицы данных ".

Сообщение "event"

M//E/context_name/event_name/event_level/event_ID/event_listener_ID/data_table/server_timestamp

Это сообщение отправляется клиенту, когда событие , именуемое event_name, происходит в context_name и этот клиент был ранее добавлен как слушатель данного события. Оно не требует ответа от клиента. Если событие постоянно, поле event_ID содержит его уникальный ID. event_listener_ID - это целое число, которое указывает на объект слушателя на стороне клиента. data_table содержит данные, специфичные для события.

Поле server_timestamp содержит время создания события на стороне сервера в миллисекундах с 1 января 1970 года 00:00:00 UTC.

Примечание: Сообщение "событие" имеет пустой параметр message_ID.

Операции

Операция "Получить переменную"

M/message_id/O/G/context_name/variable_name

Данная операция возвращает variable_nameиз context_name.

Если переменная найдена и не возникло ошибок, то в ответе на эту команду будет указана таблица данных, содержащая значение запрошенной переменной:

R/reply_id/A/data_table

Операция "Задать переменную"

M/message_id/O/S/context_name/variable_name/data_table/queue_name

Данная операция устанавливает variable_name из context_nameв значение, содержащееся в data_table.

Если указано имя_очереди, обработка выполняется в очереди имен, которая гарантирует последовательную обработку всех команд в порядке их отправки.

Если значение переменной было успешно изменено, сервер отвечает:

R/reply_id/A

Операция "Вызов функции"

M/message_id/O/C/context_name/function_name/data_table[[/queue_name]/flags]

Данная операция вызывает function_name из context_nameс data_table в качестве входных данных.

Если указано queue_name и оно не пустое, обработка выполняется в очереди имен, что гарантирует последовательную обработку всех команд в порядке их отправки.

Операция опционально поддерживает следующие флаги:

N

Нет ответа. Флаг означает, что вызывающая сторона уже вернула ответ с возвращаемым значением функции по умолчанию. В данном случае вызывающая сторона может просто выполнить функцию и не отправлять ответ. Флаг может быть использован для уменьшения трафика связи.

Если ошибка не произошла и флаг N не указан, ответ включает таблицу данных, содержащую вывод функции:

R/reply_id/A/data_table

Операция "Добавить слушателя событий"

M/message_id/O/L/context_name/event_name/event_listener_ID[/filter_text]

Данная операция зарегистрирует слушателя с указанным Integer event_listener_ID для события_name в context_name. Когда событие произошло, клиент получает сообщение "Событие"(E) с тем же кодом event_listener_ID.

Необязательный параметр filter_text позволяет предварительно отфильтровать события на основе предоставленного выражения фильтра. Данное выражение будет вычислено для каждого совпадающего события, и если его результат будет равен false, событие не будет отправлено клиенту.

Среда вычисления выражения фильтрации:

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

Нет.

Таблица данных по умолчанию

Таблица данных, содержащая специфические для события данные.

Строка по умолчанию

0

Переменные окружения

Только стандартные переменные.

При успешном добавлении слушателя событий сервер отвечает:

R/reply_id/A

Операция "Удалить слушателя событий"

M/message_id/O/R/context_name/event_name/event_listener_ID[/filter_text]

Данная операция удаляет слушателя с указанным event_listener_ID из event_nameв context_name. Если указан filter_text, удаляется только слушатель с этим фильтром.

Успешно удалив слушателя, сервер отвечает:

R/reply_id/A

Кодирование таблиц данных

Все значения данных, полученные или отправленные в рамках данного протокола, представлены Таблицами данных.

Каждая Таблица Данных закодирована в массив байт для вставки в команду.

Подробности см. в разделе Кодирование таблиц данных.