Рубрики
Без рубрики

Сервирование кликабельная масштабируемая векторная графика (SVG) Часть 3

В этом руководстве рассматриваются информация об использовании модуля Node.js в сочетании с предыдущими учебными частями, которые создают веб-сервер Express.js и анимированный HTML.

Автор оригинала: Richard Leddy.

Петри чистый государственный процесс управления (как часть экспресс-сервера)

P1.PNG.PNG

В этом руководстве предполагает некоторые знания JavaScript, HTML и Node.js

SVG Масштабируемая векторная графика – это часть HTML5. Это также язык разметки.

SVG Допускает рендеринг графики в виде линейных рисунков. Вы делаете чертежи, которые выглядят как HTML-страница. Или вы можете создавать художественные мастер-кусочки.

Продолжая от предыдущего поста, SVG часть 2

Мы уже прошли несколько шагов, чтобы получить файл готов:

  • Создайте графику SVG для обслуживания на странице.
  • Сделайте небольшую утилиту JavaScript для создания некоторых кода для инструментов анимации.
  • Настройте простой сервер Node.js с использованием Express для обслуживания страницы

Последний шаг по сути сделан. Но есть все важная часть этого, которая связана с запуском чистого менеджера штата Петри, который не был полностью адресован. В последней части этого учебника SVG PART 2 WHE мы запустили дочерний процесс, который мог бы отправить информацию о состоянии веб-сервера, что, в свою очередь, отправит информацию всем клиентам прослушивания в веб-браузерах. Тем не менее, это сделало немного больше.

Итак, в этой части учебника Часть 3 , мы можем исследовать загрузку в настоящем Чистом штате Петри. Реальный относительно. Но мы можем использовать простой модуль узла, который запускает Petri-Net и может использоваться в небольшой встроенной системе для управления взаимосвязи между аппаратными элементами. Это модуль Node.js тоже называется Run-Petri Отказ И у меня есть это доступно на Github: Run-Petri Отказ

Итак, эта часть учебника заключается в том, что эта заметка:

    • Включите рабочий детский процесс, который управляет государством Петри.

Следует пройти несколько шагов, прежде чем мы сможем получить живую страницу. Вот что осталось сделать:

  • Создать JavaScript, который будет анимировать SVG
  • Запустите страницу в браузере.

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

Еще один скрипт поддержки

DevOps никогда не делается, то есть, если вы называете некоторые из наших сценариев поддержки DEVOPS. В первой части одной из этой учебной части части 1 мы нашли способ прочитать информацию от SVG и выпускающих структур JSON, которые описывают сеть Петри, наблюдаемую в SVG. Сурок, что приходилось делать умным с именами на имя SVG-элементов и использование факта, что SVG является своего рода формат XML.

Выход из инструментов, сделанных там созданных файлов JSON, которые окажутся полезными для настройки операций на веб-страницах. Но модуль узла мы скоро будем использовать, Run-Petri , использует немного другой структуру данных JSON для инициализации. На самом деле, у него примерно такая же информация, которую мы получили от графика. Итак, вы можете догадаться, что это будет легко сделать инструмент для преобразования одного представления JSON в другое. И это происходит так.

На самом деле, вот код для него:

var fs = require('fs');  // we will be reading from files.
var scraperOutput = process.argv[2];  // named on the command line.

// Here is how to turn the text into a JSON data structure
// for use in JavaScritp
var petridDef = fs.readFileSync(scraperOutput,'ascii').toString();
petridDef = JSON.parse(petridDef);

// This is the high level structure of the JSON file 
// that is required input to a run-petri application.
var runPetriConf = {
    "nodes" : [],
    "transitions" : []
};

// An easy -- cheesy -- way to ensure no duplicates in a node list. 
function nodeDuplicates(nodeList) {
    var asObject = {};
    nodeList.forEach((name) => { asObject[name] = 1; });
    nodeList = Object.keys(asObject);
    return(nodeList);
}

//
// injectNodeList -- puts node objects into the config node list
function injectNodeList(nodeList,nodeType) {
    nodeList = nodeDuplicates(nodeList)
    nodeList.forEach((nodeId) => {
               runPetriConf.nodes.push({ "id" : nodeId, "type" : nodeType })
        });
}

//  injectNodes -- puts all the types into our list.
//  Here you can see the who the formats differ. 
//  One uses an array for each type of node.
//  The other labels a node with its type.
//  And, the way run-petri works, it just wants to run through a list and setup
//  each node type.
function injectNodes(petriData) {
    injectNodeList(petriData.inputs,"source");
    injectNodeList(petriData.outputs,"exit");
    injectNodeList(petriData.states,"state");
}

// Transitions are a separate thing in both formats.
// In fact, the are almost the same. But, this is a format switch
// from an object with transition name keys, to an array of transition objects
// each of which has a label to identify it.
function injectTransitions(petriData) {
    var transObject = petriData.transitions;
    for ( var transName in transObject ) {
        runPetriConf.transitions.push({
                              "label" : transName,
                              "inputs" : transObject[transName].inputs,
                              "outputs" : transObject[transName].outputs
                          });
    }

}

// Put the nodes into the configuration
injectNodes(petridDef);
// Put the transitions into the configurations.
injectTransitions(petridDef);

// Be lazy and dump this to the console.
console.log(JSON.stringify(runPetriConf,null,2))

Примечание : Stringify важно. Цитаты должны появиться в формате JSON.

Итак, вы видите, что большая часть разницы в форматах является то, что один формат использует объекты, клавиши которых определяют элемент чистого числа Petri, в то время как другой формат представляет собой перечисление массивов объектов, каждый из которых содержит метку NET PETRI NET.

Поскольку это отбрасывает формат в консоль, вы можете бросить его содержимое в файл правой командой оболочки как таковой:

node prepareRunPetri p1.json > petriConf.json

Выход в файл должен выглядеть похоже на это:

{ "nodes" :
   [ { "id" : "circle-input-C", "type" : "source" },
     { "id" : "circle-input-A", "type" : "source" },
     { "id" : "circle-input-D", "type" : "source" },
     { "id" : "circle-input-E", "type" : "source" },
     { "id" : "circle-input-B", "type" : "source" },
     { "id" : "circle-output-Q", "type" : "exit" },
     { "id" : "circle-output-P", "type" : "exit" },
     { "id" : "circle-state-F", "type" : "state" },
     { "id" : "circle-state-G", "type" : "state" },
     { "id" : "circle-state-H", "type" : "state" } ],
  "transitions" :
   [ { "label" : "rect-transition-A:B-F",
       "inputs" : [ "circle-input-A", "circle-input-B" ],
       "outputs" : [ "circle-state-F" ] },
     { "label" : "rect-transition-C-G",
       "inputs" : [ "circle-input-C" ],
       "outputs" : [ "circle-state-G" ] },
     { "label" : "rect-transition-F:G-P",
       "inputs" : [ "circle-state-F", "circle-state-G" ],
       "outputs" : [ "circle-output-P" ] },
     { "label" : "rect-transition-H-Q",
       "inputs" : [ "circle-state-H" ],
       "outputs" : [ "circle-output-Q" ] } ] }

Чистый государственный штат Петри

Теперь давайте обратим наше внимание на сценарий Node.js, который вырезан с сервера Express. Напомним, что мы создаем связь между ребенком в файле Petrustate.js В Express Server мы разработали во второй части этого учебника SVG Часть 2 Отказ

Но на данный момент код выглядит так:

process.on('message', (m) => {
  console.log('CHILD got message:', m);
});

setInterval(() => {
                process.send({ state: 'OK', data: "ready" });
            },1000)

Это довольно бессмысленный код.

Мы можем начать получать значимые, если мы по крайней мере, требуем Run-Petri модуль. Вот это для начала:

const PetriClasses = require('run-petri');
const pNode = PetriClasses.pNode;
const RunPetri = PetriClasses.RunPetri;

process.on('message', (m) => {
  console.log('CHILD got message:', m);
});

setInterval(() => {
                process.send({ state: 'OK', data: "ready" });
            },1000)

Обратите внимание на небольшое изменение кода в верхней части файла. PetricLasses – это модуль контейнера, который подвергает определениям классов. Первый – Pnode, узел Петри чистый. И, второй – класс RunPetri, который является классом, который ранит A Run-Petri Файл конфигурации (наш P1.JSON) и имеет методы, чтобы предпринять ресурсы, выходы излучения, и наступит в шаг сети Петри через последовательность изменений состояния.

Чтобы сделать все эти чистые линго, немного более яснее и, чтобы увидеть, как Run-Petri поможет с управлением ограниченным классом сетей, мы можем быстро перейти на тему чистую чистую петри. Я дам ссылки на более подробные обсуждения.

Немного глубже в Петри сетки и модуль Run-Petri

Итак, о Петри сетки. На верхней части страницы есть картина немаркированного на странице. Вы можете видеть, что они являются Directect Acyclic Gamps, которые имеют два типа узлов. Есть круги, ссылающиеся как Места и ящики, ссылающиеся как Переходы Отказ

Состояние чистота Петри – это Маркировка из Места с токены Отказ То есть каждый место это помечено, будет иметь черный круг в нем. Черный круг упоминается как токен Отказ

Когда государство меняется, какие изменения – маркировка. Вот простой до и после изменения состояния на картинке:

ptrans.png.png.png.png

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

После того, как вы прочитали эту статью, вы можете оценить это Run-Petri попытки избежать путаница и конфликт Отказ Хотя он пытается сделать следующие режимы работы:

  • последовательность
  • параллельность
  • синхронизация
  • слияние
  • Приоритет/ингибирование

Итак, пожалуйста, следуйте ссылкам и получите дополнительную информацию об этих шаблонах. Как Run-Petri Делает эти шаблоны возможными своеобразными для его собственной реализации. Обратите внимание, что я говорю: «Делает эти образцы возможными». Эти шаблоны будут определены, когда вы делаете конфигурацию для Run-Petri Отказ Это работа Run-Petri разрешить эти шаблоны работать.

То, что я хочу сделать сейчас, расскажет вам больше о модуле, который мы будем использовать, Run-Petri Отказ

Модуль Node.js Run-Petri

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

Установка NPM

  npm install run-petri

источники и выходы

Модуль Node.js, Run-Petri , идентифицирует два типа мест, узлов, которые позволяют данные для ввода и выхода из сети. Помещение данных в сеть соответствует, примерно, для создания более токенов для маркировки.

Модуль Node.js, Run-Petri Предоставляет средства для уточнения обработчиков и обратных вызовов для таких видов узлов.

Вот фрагмент кода, который устанавливает экземпляр RunPetri.

var pNet = new RunPetri();

// initialize the network here. note: two parameters, no special cases.
pNet.setNetworkFromJson(net_def,callbackGenerator);

Вы можете увидеть метод, setnetworkfromjsson быть вызываемым. Это имеет недвижимость, который является обратным вызовом, callbackgenerator Отказ Это функция, которая генерирует обратные вызовы по типу. Он сам имеет два параметра, ID и CBType Первый – это идентификатор узла и второй – тип узла, «выход» и т. Д.

См. Пример ниже для получения дополнительной информации.

Ресурсы

Run-Petri Относится к счетам в случае по умолчанию в качестве ресурсов. В случае по умолчанию все жетоны являются только подсчитанным держателем места на узле. И все дуги проходят по одному токену. Вы можете сделать больше с Run-Petri Отказ Я не собираюсь здесь здесь. Для этого учебника я использую дело по умолчанию.

некоторые полезные факты о его реализации

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

Если файл конфигурации имеет Смущение и Конфликты Экземпл RunPetri будет выбрасывать исключение.

В Run-Petri Один рода узла может действовать как ингибитор перехода, предотвращая его стрельба, если оно помечено. Это единственные узлы, которые могут быть использованы в качестве входа более одного раза. Они указаны как имеющие тип «inihibit», и они также требуют перехода целевого перехода. Если вы должны использовать их, формат их спецификации в списке узлов конфигурации JSON следующий следующим образом:

{ id: 'circle-input-C', type: 'inhibit', target : 'some transition label' }

Простой рабочий пример

Вот некоторые, изменение файла Petristate.js, созданного в последней части этого руководства, SVG часть 2

const fs = require('fs');

var PetriClasses = require('./index.js');
var pNode = PetriClasses.pNode;
var RunPetri = PetriClasses.RunPetri;

const nodeClasses = { pNode };

const gInterval = 2000;

const filename = "./pstate.json";  // load a particular file.
var jsonData = fs.readFileSync(filename,'ascii').toString();
var net_def = JSON.parse(jsonData);  // into a data structure.


/*  */

function callbackGenerator(id,cbType) {
    if ( cbType === 'exit' ) {  
    	// An exit callback that send data back to the parent Server.
        var dataExitCb = (v) => { process.send({ state: 'data', id: nodeId, data: v }) }
        return(dataExitCb)
    } else if ( cbType === 'reduce' ) {  // this is the default reducer...
        var reducer = (accumulator, currentValue) => accumulator + currentValue;
        return(reducer);
    }

    return((v) => { console.log(v); return(0); })
}

var pNet = new RunPetri();
 
// initialize the network here. note: two parameters, no special cases.
pNet.setNetworkFromJson(net_def,callbackGenerator);

// >>======== ======== ======== ======== ======== ======== ========

process.on('message', (m) => {
               // A way to get data from the parent process.
               // Allow the parent process a kind of
               // message that feeds the network.
               // This is useful for testing.
               if ( m.mtype == "petri" ) {
                   pNet.emit(m.sourceNode,m.value);
               }
           });

setInterval(() => {
                pNet.step(); // step the petriNet every gInterval miliseconds
                process.send({ state: 'report', data: pNet.report() })
            },gInterval)

Теперь это настроено, чтобы принять направление от родительского процесса и отправлять его для него как для состояний, так и для данных. В коде ‘pnet.report’ отправляет данные обратно на веб-сервер, который клиент захочет использовать для анимации SVG. Но выброс данных выхода данных и вызов pnet.emit (m.sourcenode, m.value) Также имейте дело с данными, идущими и с сервера. Эти последние две формы могут быть заменены в приложении, которое больше для реального мира, имеющих связь с аппаратными модулями – скажем. Филирование ввода не изменится, но Процес. Отказ

До последней части этого учебника

Теперь у нас есть процесс, который принимает вход от какого-то места, один мы можем измениться с реальными подсистемами. Он отправляет информацию на веб-сервер, который затем отправляет сообщения всем клиентам, чтобы обновить веб-страницы. И, наконец, хранитель государства Петри может выделять результаты для прослушивания процессов.

Итак, есть еще один шаг. Мы хотим увидеть графическое представление государственных изменений на наших веб-страницах. Это тема следующая и последняя часть этого учебника, часть 4. В части 4 мы можем работать Soley на клиенте, который загружает нашу страницу SVG и анимации, когда новые сообщения приходят вместе. Клиент получит json Description из сети, одинаковое описание, которое мы сделали в части 1. Клиент будет использовать это описание для идентификации элементов SVG, которое оно получает сообщения о сервере Express.js.