Протокол связи SberMobile
Протокол связи SberMobile - это открытый, безопасный и хорошо документированный протокол, используемый для связи между серверами, агентами и веб-/десктоп-клиентами SberMobile. Связь осуществляется по одиночному TCP-соединению, которое может быть дополнительно защищено шифрованием SSL/TLS.
Протокол обеспечивает интеллектуальный удаленный доступ к единой модели данных серверов и агентов, позволяя пирам "узнавать" об их возможностях, читать и записывать свойства, выполнять операции и получать асинхронные уведомления. Если говорить кратко, то если модель данных представляет собой унифицированное представление любого устройства или ресурса, то протокол - это способ получить полный удаленный контроль над ним.
Существует несколько открытых реализаций SberMobile Протокола, включая Java и Android Java, .NET и .NET Compact, C/C++, SberMobile BASIC и т.д.
Обзор протокола
В рамках сеанса связи обе стороны обмениваются командами. Отправитель команд называется клиентом, а другая сторона - сервером:
При обмене данными между SberMobile Server и SberMobile IIoT Platform Client инициатором (клиентом) является SberMobile IIoT Platform Client.
При обмене данными между SberMobile Server и SberMobile Агентом, инициатором (клиентом) является SberMobile 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
- это отдельный символ, один из:
| Команда "Сообщение" |
| Команда "Ответ" |
command_parameters
- один или несколько параметров, относящихся к коду команды и разделенных символом /
.
Команды
Команда "message"
Структура этой команды выглядит следующим образом (начиная с этого момента, первый символ <STX>
и оконечный <CR>
не указываются):
M/message_ID/message_code/message_parameters...
message_ID
уникален в пределах текущей сессии.
message_code
- символ, указывающий на тип сообщения. Доступность кодов сообщений:
| Сообщение "Start" |
| Сообщение "Operation" |
| сообщение "Event" |
message_parameters
- один или несколько параметров, специфичных для кода сообщения, разделенных символом /
.
Команда "reply"
R/reply_ID/reply_code/reply_parameters...
reply_ID
должен быть равен идентификатору сообщения, на которое отвечает.
Параметрreply_code
- символ, указывающий тип ответа. Доступность кодов ответа:
| Успешно (за ним может следовать необязательный параметр |
| Отказ в доступе |
| Ошибка (может сопровождаться одним или двумя параметрами: сообщением об ошибке и/или строкой подробностей ошибки в кодировке передачи) |
| Учетная запись пользователя временно заблокирована из-за нарушения ограничений безопасности |
| Операция запрещена, так как сервер находится в режиме обслуживания |
Сообщения
Сообщение "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".
Список доступных кодов операций:
| Операция получения переменной |
| Использовать операцию установки переменной |
| Вызов функции |
| Добавить операцию слушателя событий |
| Удалить операцию слушателя событий |
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
не указан, ответ включает таблицу данных, содержащую вывод функции:
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
Кодирование таблиц данных
Все значения данных, полученные или отправленные в рамках данного протокола, представлены Таблицами данных.
Каждая Таблица Данных закодирована в массив байт для вставки в команду.
Подробности см. в разделе Кодирование таблиц данных.