BITERP / PinkRabbitMQ

Внешняя Native API компонента для взаимодействия с RabbitMQ из 1С
MIT License
264 stars 107 forks source link

Как правильно использовать на клиенте и на сервере в асинхронном режиме #21

Closed antonwantstosleep closed 4 years ago

antonwantstosleep commented 4 years ago

Здравствуйте!

Пытаюсь разобраться, как правильно подписываться на очередь. Решаю задачу:

  1. Я правильно понимаю, что в примере

    Пока Клиент.BasicConsumeMessage(Потребитель, ТекстСообщения, ТегСообщения, Таймаут) Цикл
    // Работа с компонентой
    // ...
    //
    ТекстСообщения = ""; 
    ТегСообщения = 0; // при каждой итерации очищаем память по указателю, который неявной хранится в этой переменной
    КонецЦикла;

    показан бесконечный цикл чтения для поддержания соединения, поскольку сама компонента после вызова метода Connect() через некоторое время разрывает соединение? И мне нужно проверять ТекстСообщения на непустую строку и выполнять нужные мне действия?

  2. Если да, то на сервере этот цикл следует поместить в ФоновоеЗадание, которое нужно один раз запустить, и пускай работает, верно?

  3. А как на клиенте реализовать подобный цикл, чтобы не блокировать интерфейс? Я пока понял только как ПодключитьОбработчикОжидания, который раз в 10 секунд будет выполнять этот цикл (и выходить из него, если ТекстСообщения = "" после вызова метода BasicConsumeMessage).

Спасибо!

antonwantstosleep commented 4 years ago

Я дико извиняюсь - сначала спросил, а потом попробовал.

В доках не написано, но метод BasicConsumeMessage на самом деле возвращает Истину или Ложь (и переопределяет аргументы)..

=> компоненту нужно периодически подключать на клиенте (ПодключитьОбработчикОжидания) или на сервере (ФоновоеЗадание) и получать сообщения, верно? А потом "обнулять", как написано в доках?

А у вас нет мыслей переопределить логику - чтобы компонента сама читала сообщения и уведомляла о них 1С посредством ExternalEvent и ОбработатьВнешнееСобытие? Хотя бы на клиенте (вроде на сервере такая штука не работает)?

ripreal commented 4 years ago

Компонента сама не разрывает сообщения и на клиенте она может работать в течение всего сеанса пользователя. Обнуление необходимо для того, чтобы в конце сеанса работы с компонентой очистить остатки использованной ей памяти, которые не могут быть очищены компонентой самостоятельно.

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

Спасибо за замечание в части метода BasicConsumeMessage . Поправил описание

antonwantstosleep commented 4 years ago

Компонента сама не разрывает сообщения и на клиенте она может работать в течение всего сеанса пользователя.

Если вы имели ввиду, что она сама не разрывает соединение - у меня разрывает (1.8 Linux x64). Если:

antonwantstosleep commented 4 years ago

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

Сценарий у меня вот какой.

  1. Есть сервер телефонии Asterisk, к которому подключен сервер RabbitMQ с помощью этих проектов
  2. Asterisk шлет сообщения в очередь о событиях (всякие состояния звонков).
  3. Каждый клиент 1С привязан к своему телефону.
  4. На клиентах 1С:
    • "слушаются" события (т.е. читаются сообщения), которые касаются входящих звонков, связанных с этим клиентом
    • срабатывает ПоказатьОповещениеПользователя(), если есть входящий звонок
  5. На сервере 1С:
    • "слушаются" события общего характера - например, факт пропущенного звонка
    • срабатывает запись в регистр сведений

В данный момент на клиенте у меня проблемы: прошу компоненту читать события через ПодключитьОбработчикОжидания() раз в 5 секунд. Пока она читает - интерфейс блокируется и подтормаживает.

Я понимаю, что в теории можно делать всё на сервере, а на клиентах через обработчик ожидания делать запросы к регистру сведений и, если нужно, выводить оповещения. Но хотелось сделать по принципу "каждому свое".

ripreal commented 4 years ago

По поводу разрыва соединения посмотрю. Возможно есть какая-то ошибка в коде. По поводу ВнешнегоСобытия если есть ресурсы и желание - можно внести вклад в проект пулл-реквестом. Это реализовать несложно.Скажу даже больше. В мобильной версии данной компоненты (которая не выложена здесь) у нас вполне успешно используются внешние события для получения сообщений из RAbbitMQ.

А своими силами мы можем реализовать только те задачи по развитию компоненты, с которыми сталкиваемся на проектах наших клиентов. Похожей задачи у нас пока не было.

antonwantstosleep commented 4 years ago

По поводу ВнешнегоСобытия если есть ресурсы и желание - можно внести вклад в проект пулл-реквестом. Это реализовать несложно.

Я бы с удовольствием, но C++ первый раз в жизни вижу. Вчера правил одну из вышеупомянутых библиотек wazo, чтобы сделать заголок сообщения более информативным.. нужно было сделать конкатенацию двух чаров - чуть Гугл не уничтожил своими тупыми вопросами (((

Поэтому быстрого пул реквеста от меня не ждите.

ovcharenko-di commented 4 years ago

@antonwantstosleep, думаю, стоит начать с создания issue с кратким описанием работы этой фичи

antonwantstosleep commented 4 years ago

@ovcharenko-di , я создал https://github.com/BITERP/PinkRabbitMQ/issues/23