Взаимодействие по протоколу SberMobile
В этой главе подробно описывается, как работают реализации протокола SberMobile на стороне сервера и клиента. Обратите внимание, что сервер и клиент - это логические роли, в связи с чем могут быть различные сценарии:
- В SberMobile IIoT Platform Client или SberMobile Server API-подключение к SberMobile Server, SberMobile Server играет роль сервера, а SberMobile IIoT Platform Client / API играют роль клиента
- В агенте подключение к SberMobile Server, агент играет роль сервера, а SberMobile Server выступает как клиент
- в распределенной архитектуре поставщик соединения выступает в роли сервера, в потребитель - в роли клиента
Реализация серверной стороны
Основной класс сервера подключений по протоколу SberMobile - какой-либо класс, наследованный от DefaultClientController,
например, AgentImplementationController
. Обычно этот класс создается из контролирующего потока, запущенного при принятии нового TCP подключения, т.е. данный поток имеет доступ к сокету подключения (инкапсулированный в объект BlockingChannel
).
Как только создан клиентский контроллер, контролирующий поток должен начать периодически вызывать метод контроллера run()
. Этот метод выполняет основную логику обработки данных:
- Сначала, он вызывает
AggreGateCommandParser.readCommand()
для чтения полностью определенного протокольного блока SberMobile из сокета. Вызов анализатора может блокироваться до получения достаточных данных, либо если в системе не хватает памяти для обработки поступающих данных. - Если анализатор возвращает завершенную команду
IncomingAggreGateCommand
, контроллер ставит эту команду в очередь вCommandQueueManager
и предъявляет задачу на обработку команды своемуExecutorService
. Задача будет обрабатываться в отдельном пуле потоков, который был предоставлен в качестве аргумента конструктору клиентского контроллера.
Каждая задача обработки команды делает следующее:
- Выполняет запрошенную операцию (Get/Set Variable, Call Function или Subscribe/Unsubscribe to Events) и формирует ответ
OutgoingAggreGateCommand
- Обрабатывает очередь ожидающих событий (если какие-то события, на которые подписан текущий клиент, были добавлены в очередь после последней обработки команд) и отправляет каждое событие клиенту как отдельную
OutgoingAggreGateCommand
- Отправляет ответ оригинальной команде
Реализация клиентской стороны
Основной класс клиента подключений по протоколу SberMobile - специфичная реализация AbstractAggreGateDeviceController
, такая как RemoteServerController
. Контроллер отвечает за:
- установку TCP соединения с сервером, разбор входящих команд через
CommandParser
и отправку ответов - реализацию логики авторизации (входа)
- поддержание прокси контекстного дерева контекстов удаленного сервера (представленных экземплярами
ProxyContext
) - работу в качеству потока
AsyncCommandProcessor
, который читает и обрабатывает входящие данные
Обработчик асинхронных команд работает все время, пока есть соединение с сервером. Поток выполняет следующий цикл:
- Использование
AggreGateCommandParser.readCommand()
для чтения полностью определенного протокольного блока SberMobile из сокета - Если команда асинхронная, (т.е. получен экземпляр события), задача на ее обработку немедленно добавляется к пулу потоков обработки отдельных событий (обычно это пул из одного потока)
- Если команда синхронная, обработчик команд проверяет свою очередь ранее отправленных команд, чтобы найти команду с таким же ID, как и полученный ответ от сервера
- Как только такая команда найдена, ее
ReplyMonitor
получает оповещение, которое разблокирует поток, инициировавший какую-либо синхронную операцию сервера (Get/Set Variable, Call Function или Subscribe/Unsubscribe to Events)
Прокси контексты контекстного дерева контроллера сервера обеспечивает перенаправление всех основных вызовов на сервер и блокировку до получения ответа с использованием описанного механизма.