Взаимодействие по протоколу 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)

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