Слушатель (listener) в ABAP

Речь пойдет об прослушивании одного процесса другим. Данная функциональность в ABAP не представлена т.к. в языке нет потоков в классическом понимании этого слова. Однако, комбинируя некоторыми дополнительными возможностями, можно добиться эффекта listener’а.

Listener представляет из себя отдельный поток, который наблюдает за чем-то, например пока внутреннее состояние объекта не изменилось, запись в базу данный или пользователь не нажал на кнопку и т.д. Как только произошло действие за которым мы наблюдаем, к нам в основную программу (основной поток) возвращается информация об этом.

Принцип реализации

Есть в ABAP такая штука, как ABAP Channels. Позволяет делать соединение между двумя процессами.

Для настройки есть транзакция SAMC.

В качестве примера я сделаю приложение — чат. Для начала мне нужно создать программу Z92_CHAT и группу функций Z92TASK_CONNECTOR.

После этого можно открывать транзакцию по настройки каналов SAMC.

Как только откроете транзакцию слева будет дерево объектов, нажимаем правой кнопкой мыши и создаем свой канал. Я назову свой Z_CHANNEL_TEST. В блоке channels создам канал teleport.

Message Type ID будет text, Activity Scope — Client.

Далее необходимо добавить программы с которыми мы будем работать. В качестве отправителя сообщений у меня будет Z92_CHAT, в качестве получателя группа функций Z92TASK_CONNECTOR.

В конечном итоге получается следующая настройка

Открываем программу Z92_CHAT, пишем следующий код.

Открываем группу функций Z92TASK_CONNECTOR, создаем функциональный модуль Z92_CONNECTOR (у ФМ должен быть выходной параметр типа string, понадобится в будущем).

В ФМ нужно создать класс для имплементации интерфейса if_amc_message_receiver_text, он содержит только один метод RECEIVE. А так же добавим глобальную переменную message.

В код ФМ нужно создать класс соединения с каналом, поставить прослушивать наш канал с обработчиком, который описан выше.

В какой-то момент фм будет просто «висеть» и ждать либо пока сообщение не придет, либо пока не пройдет 1000 секунд. Соответственно условие для wait может быть любым логическим выражением, но время ожидания должно быть обязательно.

Пример для демонстрации готов, запускаем фм Z92_CONNECTOR, затем программу Z92_CHAT.

В окне запуска ФМ у меня показалось следующие сообщение

Как видно по скрину, канал был успешно настроен сообщение из программы пришло в ФМ.

Реализация чата

Первым делом в ФМ строку вывода сообщения заменяем на следующую

В свойствах ФМ нужно поставить «Дистанционный модуль». После этого Z92_CONNECTOR править больше не нужно.

Далее что бы добиться полноценной работы слушателя, что бы приложение не висело в ожидании, будем это ожидание выносить в отдельный процесс при помощи ключевого слова starting new task.

Текст чата я буду выводить в обычный ALV, так же на экране у меня будет поле ввода сообщения с повешенным на него USER-COMMAND при нажатии на ENTER.

PBO экрана

PAI экрана

В ucomm ENTER по мимо сообщения, я добавляю текущее время и имя пользователя. Осталось описать логику исполнения после того, как листенер отработал т.е. сообщение пришло. У меня это подпрограмма GIVE_FM_DATA

Тут происходит следующее: сообщение приходит, сплитится и добавляется в во внутреннюю таблицу, в последней строчке листенер перезапускается. Если посмотреть на листинг по выше, реализацию user-command OKCD, то можно увидеть, что там обновляется грид и по новой запускается наш ФМ в отдельном процессе.

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

Исходный код

Исходный код можно найти по ссылке.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *