Skip to Content
Primo RPA OrchestratorСистемным администраторамТонкая настройкаВзаимодействие служб WebApi и RDP2 по протоколу MQTT

Взаимодействие Orchestrator и RDP2 через MQTT

Доступно с версии 1.25.9+

Реализован новый событийный метод взаимодействия между службами Orchestrator (WebApi) и RDP2 через протокол MQTT-over-WebSockets с использованием RabbitMQ в качестве брокера сообщений. Этот подход решает задачи масштабирования системы и снижает нагрузку при управлении большим количеством RDP-сессий.

Преимущества MQTT-over-WebSockets

  • WebApi стал работать в двух режимах одновременно, обеспечивая обратную совместимость со старыми версиями RDP2 по HTTP и поддерживая новый режим по MQTT.
  • RDP2 можно переключить в новый режим работы через конфигурационный файл с последующим перезапуском службы.
  • Взаимодействие включает обмен сообщениями о статусах сессий, команды на завершение и уведомления о состоянии служб.

Сравнение методов взаимодействия

1. Действующий метод: взаимодействие через REST API

Служба RDP2 периодически опрашивает WebApi с помощью REST-запросов для получения списка сессий и отправки их статусов.

Цикл обработки сессий через REST API:

Основные операции:

  1. GET /api/RdpSessions?addressFilter={filterString}
    → Получение списка сессий для обработки

  2. PUT /api/RdpSessions/UpdateConnectionStatuses
    → Отправка обновленных статусов сессий

  3. GET /api/RdpSessions/CheckNoRdpPeriods?addressFilter={filterString}
    → Инициация проверки периодов простоя

  4. PUT /api/RdpSessions/{id}/SetNeedForLogOffRDPSessionUser
    → Команда на завершение сессии RDP

2. Новый метод: взаимодействие по протоколу MQTT-over-WebSockets

Взаимодействие построено на обмене сообщениями через шину RabbitMQ.

  • WebApi публикует команды и данные о сессиях (например, создать сессию).
  • RDP2 подписывается на соответствующие темы, выполняет команды и публикует статусы сессий и служебные уведомления.
1. Уведомление о состоянии службы RDP2 (RdpServiceNoticeMessage)

При запуске или остановке служба RDP2 отправляет сообщение RdpServiceNoticeMessage:

/// <summary> /// Уведомление о состоянии службы RDP2 /// </summary> public class RdpServiceNotice { /// <summary> /// Фильтр адресов обслуживаемых машин (пусто = все доступные адреса) /// </summary> public string AddressFilter { get; set; } /// <summary> /// IP-адрес машины со службой RDP2 /// </summary> public string Host { get; set; } /// <summary> /// Флаг запуска/останова службы RDP2. /// </summary> public bool IsStarted { get; set; } }

Процесс обработки уведомлений службы RDP2:

  1. RDP2 публикует RdpServiceNoticeMessage при старте/остановке
  2. WebApi сохраняет информацию в таблицу Rdp2AddressFilters
  3. WebApi отправляет полный список сессий для данной службы RDP2
  4. WebApi отправляет список через сообщение RdpSessionDataMessage

Модель данных сессии RDP

public class RdpSessionData { public int Id { get; set; } /// <summary>Имя RDP-пользователя (административное)</summary> public string AdminName { get; set; } /// <summary>Имя RDP-пользователя</summary> public string UserName { get; set; } /// <summary>Пароль пользователя</summary> public string Password { get; set; } /// <summary>IP-адрес удаленного компьютера</summary> public string Address { get; set; } /// <summary>Активна ли пауза без сессий роботов</summary> public bool IsNoRdpPause { get; set; } /// <summary>Требуется ли пауза без сессий роботов</summary> public bool NeedNoRdpPause { get; set; } /// <summary>Длительность паузы в секундах</summary> public int NoRdpPauseDurationInSeconds { get; set; } = 60; /// <summary>Поддерживать RDP-сессию постоянно</summary> public bool KeepRdpSession { get; set; } public bool UserProfileLoaded { get; set; } public int AuthenticationLevel { get; set; } public bool NegotiateSecurityLayer { get; set; } public bool EnableCredSspSupport { get; set; } /// <summary>Параметры подключения</summary> public int DesktopWidth { get; set; } public int DesktopHeight { get; set; } public int ColorDepth { get; set; } /// <summary>Статус подключения</summary> public bool Connected { get; set; } public DateTime? ConnectedChangedAt { get; set; } public DateTime? ConnectedUpdatedAt { get; set; } public int WorkerId { get; set; } public int? RdpPort { get; set; } /// <summary>Принудительное поддержание сессии (только Windows RDP)</summary> public bool? ForceKeepRdpSession { get; set; } }

3. Управление сессиями через шину сообщений

Распределение сессий:

  • WebApi отправляет RdpSessionDataMessage с сессиями для конкретной службы RDP2
  • RDP2 сохраняет сессии во внутреннем кэше

Мониторинг и управление:

  1. RDP2 регулярно проверяет состояние сессий из кэша
  2. Автоматически запускает/останавливает сессии по необходимости
  3. Публикует статусы сессий после каждого цикла проверки

4. Команда на завершение сессии (RdpSetNeedForLogoffMessage)

После обработки сессий RDP2 отправляет RdpSessionStatusesMessage:

/// <summary> /// Статус RDP-сессии /// </summary> public sealed class RdpSessionStatus { /// <summary>ID сессии</summary> public int SessionId { get; set; } /// <summary>Статус подключения</summary> public bool Connected { get; set; } /// <summary>Время изменения статуса подключения</summary> public DateTime ConnectedChangedAt { get; set; } /// <summary>Время последнего обновления статуса</summary> public DateTime ConnectedUpdatedAt { get; set; } }

Настройка нового метода взаимодействия

Для перевода взаимодействия между WebApi и RDP2 на новый режим требуется выполнить следующие шаги:

Шаг 1: Настройка RabbitMQ

На сервере с установленным RabbitMQ выполните следующие команды (для Windows — в C:\Program Files\RabbitMQ Server\rabbitmq_server-<Версия>\sbin)

rabbitmq-plugins enable rabbitmq_mqtt rabbitmq-plugins enable rabbitmq_web_mqtt

Настройка брандмауэра: Откройте TCP-порт 15675, который используется для MQTT-over-WebSockets.

Шаг 2: Настройка NGINX

Добавьте в конфигурационный файл nginx.conf блок для проксирования MQTT-трафика.

http { ... upstream mqtt { server <IP_или_имя_сервера_RabbitMQ>:15675; } server { ... location /mqtt/ { proxy_pass http://mqtt; rewrite ^/mqtt/(.*)$ /$1 break; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } ... } }

Проверьте конфигурацию:

nginx -t

в случае отсутствия ошибок, перезапустите службу NGINX:

nginx -s reload

Шаг 3: Настройка службы WebApi

В конфигурационном файле appsettings.Production.json (или другом актуальном) добавьте раздел Mqtt.

{ ..., "Mqtt": { "Url": "wss://<IP или имя и порт сервера NGINX>/mqtt/ws", "Username": "<пользователь RabbitMQ>", "Password": "<(зашифрованный) пароль пользователя RabbitMQ>" }, ... }

Важно: WebApi начнет работать в двух режимах одновременно, отправляя сообщения в шину и продолжая отвечать на REST-запросы от старых версий RDP2.

Шаг 4: Настройка службы RDP2

В конфигурационном файле службы RDP2 (appsettings.Production.json) добавьте аналогичный раздел Mqtt.

{ ..., "Mqtt": { "Url": "wss://<IP или имя и порт сервера NGINX>/mqtt/ws", "Username": "<пользователь RabbitMQ>", "Password": "<(зашифрованный) пароль пользователя RabbitMQ>" }, ... }

Проверка работоспособности

  1. Убедитесь, что службы RabbitMQ и NGINX запущены.
  2. Перезапустите службы WebApi и RDP2.
  3. В логах RDP2 при запуске должно быть сообщение об успешном подключении к MQTT-брокеру и публикации уведомления RdpServiceNoticeMessage. В логах WebApi должно быть сообщение о получении уведомления RdpServiceNoticeMessage от службы RDP2.
  4. В интерфейсе Orchestrator статусы RDP-сессий должны обновляться без задержек.
⚠️

Для работы MQTT необходимо наличие раздела Mqtt с корректным значением Url. При отсутствии этих настроек система автоматически переходит на взаимодействие через REST API.

Возврат к REST API

При проблемах с MQTT временно удалите раздел Mqtt из конфигурации для возврата к старому методу.