Creatio development guide
PDF
Документация по разработке
Описание платформы
Это документация Creatio версии 7.12.0. Мы рекомендуем использовать новую версию документации.

Sandbox. Обмен сообщениями между модулями

Glossary Item Box

Общие сведения

Модуль в bpm'online является изолированной программной единицей. Ему ничего не известно об остальных модулях системы, кроме списка имен модулей, от которых он сам зависит. Подробнее модули bpm'online описываются в статье "Принципы модульной разработки в bpm'online".

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

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

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

К СВЕДЕНИЮ

Указывать базовые модули в зависимостях ["ext-base", "terrasoft", "sandbox"] не обязательно, если модуль экспортирует конструктор класса. Объекты Ext, Terrasoft и sandbox после создания объекта класса модуля будут доступны как свойства объекта: this.Ext, this.Terrasoft, this.sandbox.

Регистрация сообщений

Чтобы модули могли обмениваться сообщениями, сообщения необходимо зарегистрировать.

К СВЕДЕНИЮ

Регистрация сообщений выполняется автоматически, если они объявлены в свойстве messages модуля.

Для регистрации сообщений модуля предназначен метод sandbox.registerMessages(messageConfig), где messageConfig — конфигурационный объект сообщений модуля.

Конфигурационный объект является коллекцией "ключ-значение", в которой каждый элемент имеет следующий вид:

"MessageName": {
    mode: [Режим работы сообщения],
    direction: [Направление сообщения]
}

Здесь "MessageName" — ключ элемента коллекции, содержащий имя сообщения. Значением является конфигурационный объект, содержащий два свойства:

  • mode — режим работы сообщения. Должно содержать значение перечисления Terrasoft.MessageMode (Terrasoft.core.enums.MessageMode).
  • direction — направление сообщения. Должно содержать значение перечисления Terrasoft.MessageDirectionType (Terrasoft.core.enums.MessageDirectionType).

Режимы обмена сообщениями (свойство mode):

  • Широковещательный — режим работы сообщения, при котором количество подписчиков заранее неизвестно. Соответствует значению перечисления Terrasoft.MessageMode.BROADCAST.
  • Адресный — режим работы сообщения, при котором сообщение может быть обработано только одним подписчиком. Соответствует значению перечисления Terrasoft.MessageMode.PTP.

ВАЖНО

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

Направления сообщения (свойство direction):

  • Публикация — модуль может только опубликовать сообщение в sandbox. Соответствует значению перечисления Terrasoft.MessageDirectionType.PUBLISH.
  • Подписка — модуль может только подписаться на сообщение, опубликованное из другого модуля. Соответствует значению перечисления Terrasoft.MessageDirectionType.SUBSCRIBE.
  • Двунаправленное — позволяет публиковать и подписываться на одно и то же сообщение в разных экземплярах одного и того же класса или в рамках одной и той же иерархии наследования схем (см. "Sandbox. Двунаправленные сообщения"). Соответствует значению перечисления Terrasoft.MessageDirectionType.BIDIRECTIONAL.

Пример регистрации сообщений модуля:

// Коллекция конфигурационных объектов сообщений.
var messages = {
    "MessageToSubscribe": {
        mode: Terrasoft.MessageMode.PTP,
        direction: Terrasoft.MessageDirectionType.SUBSCRIBE
    },
    "MessageToPublish": {
        mode: Terrasoft.MessageMode.BROADCAST,
        direction: Terrasoft.MessageDirectionType.PUBLISH
    }
};
// Регистрация сообщения.
this.sandbox.registerMessages(messages);

ВАЖНО

В схемах модели представления регистрировать сообщения с помощью метода sandbox.registerMessages() не нужно. Достаточно объявить конфигурационный объект сообщений в свойстве messages (см. "Сообщения. Свойство messages").

Для отказа от регистрации сообщений в модуле можно воспользоваться методом sandbox.unRegisterMessages(messages), где messages — имя или массив имен сообщений. Пример отмены регистрации сообщения:

// Отмена регистрации единичного сообщения.
this.sandbox.unRegisterMessages("MessageToSubscribe");
// Отмена регистрации массива сообщений.
this.sandbox.unRegisterMessages(["MessageToSubscribe", "MessageToPublish"]);

Добавление сообщений в схему модуля

Зарегистрировать сообщения можно также, добавив их в схему модуля с помощью дизайнера (см. "Дизайнер модуля").

Для добавления сообщения в схему модуля:

1. На вкладке [Структура] ([Structure]) дизайнера схемы модуля выделите узел [Messages] и, кликнув по нему правой кнопкой, выполните команду [Добавить] ([Add]) (рис. 1)

Рис. 1. — Добавление сообщения в структуру схемы модуля

2. Для добавленного сообщения установите необходимые свойства (рис. 2):

  • [Название] ([Name]) — имя сообщения, совпадающее с ключом в конфигурационном объекте модуля.
  • [Направление] ([Direction]) — направление сообщения. Возможные значения "Подписка" ("Follow") и "Публикация" ("Publish").
  • [Режим] ([Mode]) — режим работы сообщения. Возможные значения "Широковещательное" ("Broadcast") и "Адрес" ("Address").

Рис. 2. — Свойства сообщения

ВАЖНО

В схемах модели представления добавлять сообщения в структуру схемы не нужно.

Публикация сообщения

Для публикации сообщения предназначен метод sandbox.publish(messageName , messageArgs, tags).

Параметры метода:

  • messageName — строка, содержащая имя сообщения, например, "MessageToSubscribe".
  • messageArgs — объект, передаваемый в качестве аргумента в метод-обработчик сообщения в модуле-подписчике. Если в методе-обработчике нет входящих параметров, то параметру messageArgs необходимо присвоить значение null.
  • tags — массив тегов, позволяющий однозначно определить модуль, отправляющий сообщение. Как правило, используется значение [this.sandbox.id]. По массиву тегов sandbox определяет подписчиков и публикаторов сообщения.

К СВЕДЕНИЮ

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

Примеры вызова метода публикации сообщения:

// Публикация сообщения без аргумента и тегов.
this.sandbox.publish("MessageWithoutArgsAndTags");
// Публикация сообщения без аргументов для метода-обработчика.
this.sandbox.publish("MessageWithoutArgs", null, [this.sandbox.id]);
// Публикация сообщения с аргументом для метода-обработчика.
this.sandbox.publish("MessageWithArgs", {arg1: 5, arg2: "arg2"}, ["moduleName"]);
// Публикация сообщения с произвольным массивом тегов.
this.sandbox.publish("MessageWithCustomIds", null, ["moduleName","otherTag"]);

При публикации сообщения в адресном режиме можно получить результат его обработки подписчиком. Для этого метод-обработчик сообщения в модуле-подписчике должен вернуть соответствующий результат (см. "Подписка на сообщение"). Пример публикации такого сообщения:

// Объявление и регистрация сообщения.
var messages = {
    "MessageWithResult": {
        mode: Terrasoft.MessageMode.PTP,
        direction: Terrasoft.MessageDirectionType.PUBLISH
    }
};
this.sandbox.registerMessages(messages);
// Публикация сообщения и получение результата его обработки подписчиком.
var result = this.sandbox.publish("MessageWithResult", {arg1:5, arg2:"arg2"}, ["resultTag"]);
// Вывод результата в консоль браузера.
console.log(result);

При публикации сообщения в широковещательном режиме результат его обработки можно получить через объект, передаваемый в качестве аргумента для метода-обработчика:

// Объявление и регистрация сообщения.
var messages = {
    "MessageWithResult": {
        mode: Terrasoft.MessageMode.BROADCAST,
        direction: Terrasoft.MessageDirectionType.PUBLISH
    }
};
this.sandbox.registerMessages(messages);
var arg = {};
// Публикация сообщения и получение результата его обработки подписчиком.
// В методе-обработчике подписчика в объект нужно добавить свойство result,
// в которое следует записать результат обработки.
this.sandbox.publish("MessageWithResult", arg, ["resultTag"]);
// Вывод результата в консоль браузера.
console.log(arg.result);

Подписка на сообщение

Подписаться на сообщение можно, используя метод sandbox.subscribe(messageName, messageHandler, scope, tags).

Параметры метода:

  • messageName — строка, содержащая имя сообщения, например, "MessageToSubscribe".
  • messageHandler — метод-обработчик, вызываемый при получении сообщения. Это может быть анонимная функция или метод модуля. В определении метода может быть указан параметр, значение которого должно быть передано при публикации сообщения с помощью метода sandbox.publish().
  • scope — контекст выполнения метода-обработчика messageHandler.
  • tags— массив тегов, позволяющий однозначно определить модуль, который отправляет сообщение. По массиву тегов sandbox определяет подписчиков и публикаторов сообщения.

Примеры вызова метода подписки на сообщение:

// Подписка на сообщение без аргументов для метода-обработчика.
// Метод-обработчик — анонимная функция. Контекст выполнения — текущий модуль.
// Метод getsandboxid() должен вернуть тег, совпадающий с тегом опубликованного сообщения.
this.sandbox.subscribe("MessageWithoutArgs", function(){console.log("Message without arguments")}, this, [this.getSandBoxId()]);
// Подписка на сообщение с аргументом для метода-обработчика.
this.sandbox.subscribe("MessageWithArgs", function(args){console.log(args)}, this, ["moduleName"]);
// Подписка на сообщение с произвольным тегом.
// Тег может быть любым из массива тегов опубликованного сообщения.
// Метод-обработчик myMsgHandler должен быть реализован отдельно.
this.sandbox.subscribe("MessageWithCustomIds", this.myMsgHandler, this, ["otherTag"]);

Для сообщения в адресном режиме метод-обработчик сообщения должен вернуть соответствующий результат. Пример подписки на такое сообщение:

// Объявление и регистрация сообщения.
var messages = {
    "MessageWithResult": {
        mode: Terrasoft.MessageMode.PTP,
        direction: Terrasoft.MessageDirectionType.SUBSCRIBE
    }
};
this.sandbox.registerMessages(messages);
// Подписка на сообщение.
this.sandbox.subscribe("MessageWithResult", this.onMessageSubscribe, this, ["resultTag"]);
...            
// Метод-обработчик реализован в модуле-подписчике.
// args — объект, передаваемый при публикации сообщения.
onMessageSubscribe: function(args) {
    // Изменение параметра.
    args.arg1 = 15;
    args.arg2 = "new arg2";
    // Обязательный возврат результата.
    return args;
},

Асинхронный обмен сообщениями

Если метод-обработчик сообщения в модуле-подписчике генерирует результат асинхронно, то необходимо использовать подход с функцией обратного вызова (callback-функцией).

Пример публикации сообщения и получения результата:

this.sandbox.publish("AsyncMessageResult",
//Объект, передаваемый как аргумент функции-обработчика в подписчике.
{
    // Функция обратного вызова.
    callback: function(result) {
        this.Terrasoft.showInformation(result);
    },
    // Контекст выполнения функции обратного вызова.
    scope: this
});

Пример подписки на сообщение:

this.sandbox.subscribe("AsyncMessageResult",
// Функция-обработчик сообщения
function(config) {
    // Обработка входящего параметра.
    var config = config || {};
    var callback = config.callback;
    var scope = config.scope || this;
    // Подготовка результирующего сообщения.
    var result = "Message from callback function";
    // Выполнение функции обратного вызова.
    if (callback) {
        callback.call(scope, result);
    }
},
// Контекст выполнения функции-обработчика сообщения.
 this);

Пример модуля, использующего сообщения

Пример модуля, в котором реализована публикация и подписка на сообщение, приведен ниже:

define("UsrSomeModule", [], function() {
    Ext.define("Terrasoft.configuration.UsrSomeModule", {
        alternateClassName: "Terrasoft.UsrSomeModule",
        extend: "Terrasoft.BaseModule",
        Ext: null,
        sandbox: null,
        Terrasoft: null,
        messages: {
            "MessageToSubscribe": {
                mode: Terrasoft.MessageMode.PTP,
                direction: Terrasoft.MessageDirectionType.SUBSCRIBE
            },
            "MessageToPublish": {
                mode: Terrasoft.MessageMode.BROADCAST,
                direction: Terrasoft.MessageDirectionType.PUBLISH
            }
        },
        init: function() {
            this.callParent(arguments);
            this.sandbox.registerMessages(this.messages);
            this.processMessages();
        },
        processMessages: function() {
            this.sandbox.subscribe("MessageToSubscribe", this.onMessageSubscribe, this);
            this.sandbox.publish("MessageToPublish", null, [this.sandbox.id]);
        },
        onMessageSubscribe: function() {
            console.log("'MessageToSubscribe' received");
        },
        destroy: function() {
            if (this.messages) {
                var messages = this.Terrasoft.keys(this.messages);
                this.sandbox.unRegisterMessages(messages);
            }
            this.callParent(arguments);
        }
    });
    return Terrasoft.UsrSomeModule;
});

Смотрите также

© Terrasoft 2002-2019.

Был ли данный материал полезен?

Как можно улучшить эту статью?