Работа с HTML
Программируемые устройства Tibbo оснащены встроенным веб-сервером.
Веб-сервер поддерживает серверные сценарии: код Tibbo BASIC/C можно включить прямо в HTML-страницу и таким образом генерировать HTML-содержимое динамически.
Ниже приведены две простые программы - на Tibbo BASIC и на Tibbo C, - демонстрирующие приём динамического формирования HTML.
Чтобы полностью разобраться в этом коде, изучите объект sock.
Пока же обратите внимание на то, как код BASIC или C включается в HTML-файл: исполняемый код заключается между управляющими последовательностями <? и ?>. Всё, что находится вне <? ?>, считается обычным HTML и отправляется в браузер «как есть».
Когда встроенный HTTP-сервер получает запрос GET (или POST), он начинает отправлять запрошенный HTML-файл. Сервер читает HTML-файл сверху вниз и передаёт его содержимое в браузер без изменений - пока не встретит блок кода на BASIC или C. Дойдя до кода, сервер передаёт управление VM, и она начинает выполнять этот код.
Определять процедуры внутри HTML-файла нельзя, поскольку весь файл рассматривается как одна виртуальная процедура.
Более того, размещение кода в двух фрагментах <? ?> не делит его на две процедуры. То, что весь код каждого HTML-файла считается частью единой виртуальной процедуры, влияет на обработку событий (напомним: очередь у всех событий одна). Следующее событие в очереди не будет выполнено, пока не завершится HTML-процедура. И то, что HTML-процедура состоит из двух и более фрагментов, не означает, что другие события будут выполняться, пока HTTP-сервер отправляет статические данные между этими фрагментами. Если нужно, чтобы другие обработчики событий могли вклиниться во время генерации и отправки в браузер длинного сложного HTML-файла, используйте оператор doevents.
Обратите внимание и на то, что HTML и код BASIC/C можно перемежать.
В примере ниже есть цикл for-next, который выполняется 10 раз. Между его строками вклинена строка на HTML (<i> Foo </i>).
Поскольку эта строка расположена «внутри» цикла for-next, она тоже передаётся 10 раз. Это очень мощный приём программирования!
Иными словами, вывод файла не всегда сводится к простому проходу сверху вниз с остановкой в конце. Ваш код может заставить HTTP-сервер повторять фрагменты, ветвиться, пропускать части файла и так далее.
Ранее уже объяснялось, что в TIDE расширения файлов существуют в основном для вашего удобства. Фактический тип файла задаётся отдельно.
Диалоги Add New File to Project, Add Existing File to Project и Change File Type позволяют задать тип файла, и для HTML-файлов есть два варианта: HTML File (C) и HTML File (BASIC). Именно этот выбор определяет, какой язык ожидается внутри HTML-файла.
sub on_sys_init()
net.ip="192.168.1.201" '<=== put a suitable IP address here
dim f as byte
for f=0 to 4 'allocate five sockets for the webserver
sock.num=f
sock.txbuffrq(1)
sock.varbuffrq(1)
sock.redir(PL_REDIR_SOCK0 + sock.num)
sys.buffalloc
sock.protocol=PL_SOCK_PROTOCOL_TCP
sock.httpportlist="80"
sock.inconmode=PL_SOCK_INCONMODE_ANY_IP_ANY_PORT
next f
end sub
void on_sys_init(){
net.ip="192.168.1.201"; //<=== put a suitable IP address here
unsigned char f;
for(f=0;f<5;f++){ //allocate five sockets for the webserver
sock.num=f;
sock.txbuffrq(1);
sock.varbuffrq(1);
sock.redir(PL_REDIR_SOCK0 + sock.num);
sys.buffalloc();
sock.protocol=PL_SOCK_PROTOCOL_TCP;
sock.httpportlist="80";
sock.inconmode=PL_SOCK_INCONMODE_ANY_IP_ANY_PORT;
}
}
Приведённый выше код отправит в браузер следующее:
foo foo foo foo foo foo foo foo foo foo
END OF OUTPUT
Тот же вывод можно получить иначе. В этом примере цикл for-next программно десять раз печатает Foo:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 HTML//EN">
<HTML><BODY>
BEGINNING OF OUTPUT<br>
<?
dim f as byte
for f = 0 to 9
sock.setdata("<i> Foo </i>")
sock.send
next f
?>
<br>END OF OUTPUT<br>
</BODY></HTML>
Какой стиль программирования лучше - первый или второй? Явного победителя нет. Выбор за вами!
Поскольку внутри HTML-файла процедур нет, все переменные, определённые на «уровне HTML-файла», имеют глобальную область видимости (об этом шла речь в разделе Области видимости).
Например, переменная f в примере выше глобальная, хотя значима она только локально. Это увеличивает общий объём памяти, необходимый проекту.
Если же определить переменную внутри цикла for-next, она (разумеется) будет локальной, а не глобальной.
Итог: общий объём памяти проекта можно уменьшить, по возможности не объявляя глобальные переменные в HTML-файлах. Для этого сложный HTML-код можно заключить в процедуры и вызывать их из HTML.
Дополнительные материалы
Прежде чем вы начнёте уверенно создавать веб-приложения на Tibbo BASIC и C, нужно разобрать ещё множество нюансов.
Например, здесь не объяснялось, как получать и обрабатывать HTTP-переменные, которые часто передаются с запросами GET и POST.
Всё это и многое другое описано в документации по объекту sock. HTTP, в частности, рассматривается в разделе Использование HTTP.