Инструменты пользователя

Инструменты сайта


app

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
app [2025/10/03 11:57]
root [Создания интерфейса функции]
app [2025/10/09 09:23] (текущий)
root
Строка 130: Строка 130:
 </wrap> </wrap>
 \\ \\
-В функция **main** при запуске передается аргумент **ctx**, содержащий в себе набор объектов, посредством которых можно в дальнейшем взаимодействовать с ядром системы и другими приложениями. В начале функции из нее выбираются наиболее часто используемые объекты, и сохраняются в глобальной области видимости, для удобства дальнейшей работы с ними. В частности это:+В функцию **main** при запуске передается аргумент **ctx**, содержащий в себе набор объектов, посредством которых можно в дальнейшем взаимодействовать с ядром системы и другими приложениями. В начале функции из нее выбираются наиболее часто используемые объекты, и сохраняются в глобальной области видимости, для удобства дальнейшей работы с ними. В частности это:
 \\ \\
 <wrap ks> <wrap ks>
Строка 300: Строка 300:
  
 <wrap ks> <wrap ks>
-В данном коде мы создаем функцию с именем **myFunc** и аргументом **v**, доступную для вызова из стороннего приложения, в коде функции с аргументом производим некие математические операции и возвращаем результат исполнения функции вызывающей ее приложению. Далее создаем счетчик **cnt**, и таймер, срабатывающий раз в секунду, который вызывает нашу созданную функцию как внешнюю из нашего же приложения, передавая в качестве аргумента вызова значение счетчика **cnt**, после чего инкрементируя его. Результаты работы данного кода мы можем увидеть в системном журнале.+В коде приложения 1 мы создаем функцию с именем **myFunc** и аргументом **v**, доступную для вызова из стороннего приложения, в коде функции с аргументом производим некие математические операции и возвращаем результат исполнения функции вызывающей ее приложению. в коде приложения 2 создаем счетчик **cnt**, и таймер, срабатывающий раз в секунду, который вызывает нашу созданную функцию как внешнюю из нашего же приложения, передавая в качестве аргумента вызова значение счетчика **cnt**, после чего инкрементируя его. Результаты работы данного кода мы можем увидеть в системном журнале.
 </wrap> </wrap>
 +
 +{{ ::app9.png?nolink |}}
  
 ===== Создания интерфейса сигнала ===== ===== Создания интерфейса сигнала =====
 <wrap ks> <wrap ks>
-Сигнал, так же как и функцию, необходимо зарегистрировать в системе, чтобы сторонние приложения могли подключиться к нему для отслеживания.+Сигнал, так же как и функцию, необходимо зарегистрировать в системе, чтобы сторонние приложения могли подключиться к нему для отслеживания. Регистрация выполняется методом **regEvent** объекта **rpc**. Данный метод принимает только один аргумент - имя сигнала. Регистрация сигнала не вызывает самого сигнала, а только сообщает системе о его наличие у приложения. Вызов же события сигнала выполняется методом **emit** объекта **rpc**, в качестве первого аргумента которого передается имя вызываемого сигнала, а вторым - данные, передаваемые приложению, отслеживающему этот сигнал. Так же, для упрощения примера, весь этот код можно разместить в одном приложении.
 </wrap> </wrap>
 +<wrap ks>
 +Для примера создадим код следующего вида:
 +</wrap>
 +
 +<code javascript>
 +// код приложения 1
 +// создание сигнала
 +rpc.regEvent('myEvent');
 +
 +// вызов созданного сигнала
 +let cnt = 0;
 +setInterval(async () => {
 +    log('Вызов сигнала', cnt);
 +    rpc.emit('myEvent', cnt++);
 +}, 1000);
 +</code>
 +
 +<code javascript>
 +// код приложения 2
 +// отслеживание и обработка сигнала
 +rpc.listen('myapp.myEvent', null, (data) => {
 +    log('Получение сигнала', data);
 +});
 +</code>
 +
 +<wrap ks>
 +В коде приложения 1 мы создаем сигнал с именем **myEvent**, далее вы вызываем сигнал с интервалом раз в секунду. В коде приложения 2 мы отслеживаем события нашего сигнала. В результате выполнения данного кода мы должны увидеть в системном журнале сообщения следующего вида:
 +</wrap>
 +
 +{{ ::app10.png?nolink |}}
 +
 +====== Вызов функции из скриптов DevelSCADA ======
 +<wrap ks>
 +Помимо взаимодействия между приложениями, данный механизм позволяет работать и с пользовательскими скриптами самой системы DevelSCADA при разработке проектов посредством вызова функции [[ds.rpccall|ds.rpcCall]] ядра исполнения системы. Для примера, создадим в нашем приложении функцию, и вызовем ее из скриптов проекта.
 +</wrap>
 +<wrap ks>
 +Код приложения:
 +</wrap>
 +
 +<code javascript>
 +'use strict';
 +
 +let logCtx = null, log = null;
 +let rpc = null, cfg = null;
 +
 +async function main(ctx) {
 +    ({ logCtx, rpc, cfg } = ctx);
 +    ({ log } = logCtx);
 +    module.paths.push(ctx.modPath);
 +    
 +    rpc.regFunc('myFunc', () => {
 +        const { exec } = require('node:child_process');
 +        exec('notepad');
 +    });
 +}
 +
 +exports.main = main;
 +
 +exports.about = {
 +    mark: 'MA',
 +    descr: 'Мое приложение', 
 +    isSingle: true,
 +    isGui: false,
 +    isPm: false,
 +    order: 1000,
 +    depend: []
 +};
 +</code>
 +<wrap ks>
 +В данном приложении мы создали единственную функцию **myFunc**, которая будет из операционной системы запускать блокнот. Запустим это приложение в диспетчере приложений.
 +</wrap>
 +
 +{{ ::app5.png?nolink |}}
 +
 +<wrap ks>
 +Далее в редакторе проектов создадим новый проект, на экране разместим кнопку, и в событии кнопки "Нажатие", выберем действие "Скрипт".
 +</wrap>
 +
 +{{ ::app11.png?nolink |}}
 +
 +{{ ::app12.png?nolink |}}
 +
 +<wrap ks>
 +Далее напишем следующий код скрипта:
 +</wrap>
 +
 +<code javascript>
 +async function main(val) {
 +    await ds.rpcCall('myapp.myFunc');
 +}
 +</code>
 +
 +<wrap ks>
 +Данный код должен будет вызвать **myFunc** из приложения **myapp**. Запустим проект на исполнение и нажмем кнопку. В результате должен будет открыться блокнот.
 +</wrap>
 +
 +{{ ::app13.png?nolink |}}
 +
app.1759481835.txt.gz · Последнее изменение: 2025/10/03 11:57 — root