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

Базовые понятия

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

Термин Описание
JS JavaScript
JS-контекстсреда выполнения программы на JS
СКУ Система контроля и управления
ОС Операционная система (Windows, Lunux...)
Элеватор Функционал, позволяющий выполнять опрос устройств подключеных к последователь-ным интерфейсам из раздельных JS-контекстов.
URL Полный интернет адрес в формате xxx://addr:port/dir


Описание

jCjS предоставляет собой среду исполнения и систему ввода-вывода для программ (скриптов) написанных на языке JavaScript (ECMA-262). Порядок выполнения скриптов, набор встроенных объектов, методы добавления встроенных объектов регламентируются действующей документацией.

jCjS предназначен для построения различных систем автоматизации и управления (СКУ), что отражено в методологии, структуре и правилах работы с программой. Область применения jCjS не ограничено СКУ и, в ряде случаев, jCjS может быть адаптирован для решения других задач, связанных с интеграцией интерпретатора JavaScript и компилируемого С++ кода с применением библиотеки Qt.

Как часть системы ввода-вывода jCjS содержит в своем составе HTTP сервер, поддерживающий минимально-достаточное подмножество протокола HTTP/1.1 (RFC2068).

Формирование HTTP ответа осуществляется выполнением специализированного скрипта-обработчика события, при этом доступ к параметрам HTTP запроса осуществляется через встроенный в JS-контекст объект.

Набор встроенных объектов JavaScript может быть расширен за счет плагин системы. Назначение каждого конкретного плагина не регламентируется, и может заключаться,

Порядок написания, компиляции и внедрения плагинов описан в документации. Предусмотрена возможность использования исходных кодов плагинов для "жесткой прошивки" их функционала в исполняемый файл jCjS.

В зависимости от настроек jCjS, возможна одновременная работа нескольких процессов jCjS с различными настройками HTTP порта и/или одновременная работа нескольких интерпретаторов JavaScript. Каждый экземпляр интерпретатора хранит набор параметров, отвечающих за логически выделенную и независимую подсистему. Встроенный сервер перенаправляет HTTP запросы определенному интерпретатору JavaScript в соответствии с параметрами URL.

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

jCjS (Gui-версия) имеет в своем составе встроенный отладчик скриптов, позволяющий останавливать выполнение скрипта в точках останова, с возможностью просмотра локальных переменных.

Ограничение доступа к файлам.

Организация встроенных объектов скриптов имеющих доступ к файловой системе ограничивает их в доступе в пределах назначенных в настройках сервера директорий и их поддиректорий. Ограничение доступа к файлам сервера: настроечные файлы, файлы скриптов и страниц HTML осуществляется администратором ОС средствами ОС.

Настроечный файл в формате XML позволяет описать древовидную структуру настроечных данных сервера и постов (см. раздел Конфигурация).

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

Элеватор заданий на последовательных портах.

В ядро jCjS входит элеватор заданий на последовательных портах (далее элеватор). Он позволяет выполнять опрос устройств, подключеных к последовательным интерфейсам. Также он снимает ограничения, накладываемые требованиями на подключение устройств к последовательным интерфейсам (возможность опросить различные устройства с различными протоколами обмена и/или аппаратными настройками соединения расположенные на одном последовательном интерфейсе).

Алгоритм работы

В описании работы фигурируют три объекта, которые необходимо описать
Объект Описание
server Выполняет начальный запуск, чтение конфигурации, создание объектов post и обслуживание клиентских запросов
post Объект, в котором запускается программа JS
http server создает объект http при подключении клиетского браузера и передает его post

В момент начального пуска, jCjS обращается к конфигурационному файлу jcjs.xml, читает из него настройки сервера и описание постов, затем открывает HTTP порт и создает объекты post.
Каждый post, создает интерпретатор JavaScript (JS-контекст), объявляет в своем JS-контексте глобальные объекты server, post, jsext, scriptEngine а также специфические объекты описаные в конфигурации поста (см. строку 20 Листинга 2 раздела "Описание файла конфигурации"). Следующим шагом выполняется программа инициализации init.js и отсылается уведомление серверу, с каким статусом инициализировался (ошибка/успех).

//debug=true;

//------------------------------------------------------------
// Авторизация действий на странице поста
var r_user="Admin"
var r_pass="system"
//------------------------------------------------------------
// Разрешить глобальную регистрацию
//server.makeRegistration = true;

if(server.makeRegistration)
    post.evalScript("registration.js");
else
    post.r_auth = (server.auth != "")
            ? server.auth
            : server.toBase64(r_user+':'+r_pass);
//------------------------------------------------------------

// Выполнить системный скрипт
post.evalScript("jcjsHelper.js");

...
// Далее создание источников сигналов и их обработчиков,
// а также объектов опроса оборудования, записи в БД и т.д.

Сценарий инициализации - это JavaScript программа, в которой заложена вся автономная(не зависящая от запросов клинетских браузеров) логика работы поста.

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

После того, как вы открыли браузер и ввели в адресную строку URL, браузер инициализирует соединение с сервером jCjS по протоколу HTTP. Как только содинение становиться установленным (established), server создает объект http, и если в первой директории встречается имя поста, передает созданный объект post-у. Пост принимает объект соединения, внедряет его в свой JS-контекст и выполняет коммандный скрипт cmd.js, задача которого обслужить запрос и ответить браузеру. Следующий схематический рисунок поясняет как это происходит.

Коммандный скрипт cmd.js выполнят необходимые функции по анализу аргументов HTTP запроса, и передает запрошенные данные браузеру.

//var ans = ifFunction(ans) ? ans :
function ans()
{
   if(server.makeRegistration)
   {
       // Если в каком-то посте установлен флаг server.makeRegistration,
       // то при первом вызове будет выполнен registration.js
       if((typeof makeRegistration !== "function"))
            post.evalScript("registration.js");

        // а теперь проверка (функция из registration.js)
        if(!makeRegistration())
            return;
   }

   // Если есть аргументы GET http://adr/Post1/?arg1&arg2=2&arg3 то обслужить их
   if(http.argCnt)
   {
       /* Можно заставить браузер предложить сохранить файл на диск
       http.saveToDisk = true;
       http.contentName = http.argKeyByNum(0) + '.txt';
       */

       // Если первый агрумент server post http this, то отдать браузеру описание всех переменных запрошенного объекта
       switch(http.argKeyByNum(0))
       {
       case 'server':  http.respPlainText(JSON.stringify(server, null, 2)); return;
       case 'post':    http.respPlainText(JSON.stringify(post,   null, 2)); return;
       case 'http':    http.respPlainText(JSON.stringify(http,   null, 2)); return;
       case 'this':    http.respPlainText(JSON.stringify(this,   null, 2)); return;
       }

       // Существует возможность авторизации запросов
       switch(http.argKeyByNum(0))
       {
       case 'reg':{
                    if(!testAuth())
                    {
                        http.respError(403, 'запрос "' + http.argKeyByNum(0) + '" запрещен');
                        post.log("w", 'запрос клиента отклонен');
                        return;
                    }
                    http.respPlainText(JSON.stringify(server,   null, 2));
                  }
       return;
       }

   }//(http.argCnt)

   // Отдать статические файлы из каталога поста.
   // Функция jcjs_resp() объявлена в stuff/include/jcjsHelperResp.js
   if(jcjs_resp())
       return;

   var mess = ": не найден";
   http.respError(404, http.path + mess);
   post.log("w", http.path + mess);
   mess = '';
   return;

}

// Обработка исключительных ситуаций в работе скрипта
try{
    ans();
}           // если будет ошибка в ans(), браузер получит заголовок с ошибкой 500
catch(e)    // и будет произведено логирование детального описания ошибки в лог
{
    http.respError(500, http.path);
    post.log("e", e.fileName + ':' + e.lineNumber + ' "' + e.message + '"');
}

Останов поста

После того как jCjS получил сигнал к остановке, server закрывает все соединения и рассылает команды постам на завершение работы. Команды отсылаются в обратном инициализации порядке. Останавливается сначала последний инициализированный. Последним останавливается серверный (первый) пост.
Пост, получив команду остановки, выполняет финальный скрипт end.js, на котором лежат обязанности по завершению работы и приведению оборудованания в норамальное сотояние(закрытие клапанов, остановка двигателей и т.д).
server ожидает от постов сигнала о финале работы скрипта (функция post.finished() - обязательная в сценарии end.js)

// останов оборудования, закрытие соединений с БД и т.д.
...

// Подать сигнал что пост завершил работу
post.finished();

Если по каким-то причинам функция post.finished() не выполнена в сценарии end.js, сервер через 15 секунд принудительно завершит работу поста. (Это время можно изменить в контксте)


Далее