В предыдущих разделах документации вы рассмотрели следущее: что jCjS - это HTTP сервер,
который реагирует на событие HTTP запроса вызовом к исполнению некоторой программы на языке JavaScript,
и он, в отличие от других
традиционных серверов, которые отдают локальные файлы, может сформировать HTTP ответ
"на лету".
В этом разделе вы поймете, что
являтся снимком внутреннего состояния сервера, который при этом может постоянно изменяться
под действием внутренних событий сервера (или событий вызванных обслуживаемым оборудованием).
Эти события в сервере могут происходить независимо от того, есть к нему HTTP запросы или нет,
с другой стороны и HTTP запросы могут влиять на состояние сервера...
Итак по-порядку.
К предстоящим событиям нужна подготовка, имеются в виду события HTTP запросов. До этого момента, для простоты изложения материала, мы не занимались этим вопросос. Для последнего рассмотренного приложения jCjS выдачи времени на сервере и локальной машине этого и не требовалось. Теперь закономерный вопрос: как дополнить это приложение так, чтобы страница сайта выдавала время работы сервера? Естесственное решение: нужно в момент старта сервера создать и инициализировать текущим временем некую переменную, до того момента как придет какой-либо HTTP запрос. Для начала укажем jCjS обработчик такого события:
<?xml version="1.0" encoding="UTF-8"?>
<jСjS>
<post
objectName = "helloWorld"
description = "hello World post"
portDebug = "0"
debug = "false"
defDirs = "stuff@examples/postObject"
>
<handlers
init = "initDiffTime.js"
cmd = "cmdDiffTime.js"
/>
</post>
</jСjS>
Детальное описание конфигурационного файла (см. раздел Конфигурация)
и создадим файл initDiffTime.js с таким содержимымvar timeStart = new Date().getTime();
HTML страницу tmpDiffTime.html оставим без изменений, а командный скрипт напишите такую программу:
try{
(function() {
if(http.argCnt == 0 && http.pathCnt == 0) {
http.respFile('tmpDiffTime.html');
return;
}
if(http.argExist('time')) {
var time = new Date();
var h = time.getHours(); if(h < 10) { h = '0' + h; }
var m = time.getMinutes(); if(m < 10) { m = '0' + m; }
var s = time.getSeconds(); if(s < 10) { s = '0' + s; }
var w = (time.getTime() - timeStart) / 1000;
http.respPlainText(h + ':' + m + ':' + s + ' (' + w + ')');
return;
}
http.respError(404);
return;
})();
}
catch(e)
{
http.respError(500, http.path);
post.log("e", e.fileName + ':' + e.lineNumber + ' "' + e.message + '"');
}
Обратите внимание, рабочая функция окружена конструкцией try{}catch(){}, это необходимо в случае ошибки в командном файле, чтобы браузер на повис на долгом ожидани ответа.
Получить страницу в браузере:
Время на сервере jCjS: 17:09:13 (663.887) (delay = 24мс) Время на этой машине: 17:09:13
Теперь вам понятно назначение инициализирующего скрипта. Если в файле jcjs.xml он не указан, то никакой инициализации и не производится. Напрашивается вопрос, а есть ли обработчик окончания работы сервера? Ответ: да есть, называется end и его основное назначение состоит в приведении обслуживаемого оборудования в исходное состояние. Действительно, многое промышленное оборудование нельзя сразу взять и выключить, - возможен даже поэтапный процесс, например: включить привод крана на закрытие, дождаться закрытия, после этого обесточить привод, после этого приступить к закрытию следующего крана и т.д. Поэтому с обработчиком окончания работы end не так все просто - на самом деле в jCjS даже происходит блокирование закрытия программы пока все необходимые этапы завершения работы не выполнятся. Как это происходит конкретно, рассмотрим далее, когда непосредственно займемся работой с промышленным оборудованием.
Обычно в программировании периодические события инспирируются таймером, jCjS - не исключение, в нем тоже можно создавать таймеры и по их срабатыванию производить различные действия. Это может быть опрос показаний датчиков, обработка и передача информации в базы данных и многое другое. JavaScript, как и многие другие другие универсальные языки программирования в своем составе не имеет таймерных средств, их должна предоставлять среда исполнения. Для веб-браузеров имеются в глобальной видимости две функции: setTimeout() - разовый таймер и setInterval() - периодический таймер. В jCjS, в силу принятых библиотекой Qt особенностей интеграции C++ и JavaScript таймера создаются неким глобальным объектом post (смотрим jcjs.xml). Вот типичный код создания таймера с использованием глобального объекта post:
function funcTimer() {
...
}
var timer = new QTimer()
timer.timeout.connect(funcTimer);
post.someTimer.start(1000);
В библиотеке Qt имеется такое понятие как сигнал. Таймер имеет сигнал timeout, который соединяется c функцией обработчиком.
Для кода JavaScript на стороне сервера принято, что глобальными объектами являются либо нативные переменные и функции, либо немногочисленные синтетические объекты, пришедшие из глубин C++ кода; таких объектов мы сейчас знаем в количестве двух: http и post. Есть еще два: server и jsext и на этом их счет заканчивается.