Написание чата ничем особенным не отличается. Та же запись в файлы, чтение из них информации и вывод ее на экран. Однако есть кое-какие тонкости. Сообщения в чат поступают в режиме реального времени, поэтому для поддержания этого режима необходимо периодически обновлять содержимое html-страницы. Это осуществляется с помощью мета-инструкции <meta http-equiv="Refresh" content="10"> .В данном случае будем обновлять страницу с интервалом в 10 секунд, этого вполне достаточно. Итак, приступим непосредственно к чату.
Вход в чат
Сгенерируем форму для входа в чат.
<html><style> BODY {background-color:#e6e8fa;font-family:arial;font-size:10pt;color:#000080;} </style>
$file="chat.txt"; <span class="comment"># Файл для записи сообщений</span>
$syslog="log.txt"; <span class="comment"># Cистемный журнал</span> $online="online.txt"; <span class="comment"># Файл для записи онлайновых посетителей.</span> $dir="f:/usr/local/apache/cgi-bin"; $path="f:/usr/local/apache/cgi-bin/images/"; <span class="comment"># Путь к папке с картинками (смайликами)</span>
<span class="comment"># Назначаем переменные для смайликов.</span> @images=("smile.gif","frown.gif","redface.gif","biggrin.gif","wink.gif", "tongue.gif","cool.gif","rolleyes.gif", "mad.gif","eek.gif","confused.gif");
BODY {background-color:#e6e8fa;font-family:arial;font-size:10pt;color:#000080;} </style> <body> <center><h3>Здравствуйте,<font color="$color">$nick!</font></h3> Вы успешно вошли в чат. <br>Вы можете добавлять ваши сообщения.Ваш цвет-<font color="$color">$color</font>.</center>
<span class="comment"># Если посетитель не ввел ник,выдается ошибка.</span> else { print "Content-type:text/htmlnn"; print <<HTML; <html><style> BODY {background-color:#e6e8fa;font-family:arial;font-size:10pt;color:#000080;} </style> <body> <h3 align=center>Вы не ввели ник!</h3>
Пожалуйста,вернитесь и введите ник. <p><center><a href="chat.cgi?action=login">Назад</a></center> HTML } }
Как видите, форма имеет 2 кнопки, предусмотрена кнопка выхода из чата, а также кнопка для отправки сообщения в чат. Это будет рассмотрено далее.
Добавление сообщения в чат
После того, как посетитель ввел сообщение и нажал кнопку Отправить, сообщение записывается в файл. Ник посетителя и цвет сообщений передаются в скрытых полях формы.
<span class="comment">#########################Добавление сообщения######################### </span> ($action eq "add") && do { $time=time; <span class="comment"># Получаем текущее время в секундах.</span> $time1=scalar localtime; <span class="comment"># Время в нормальном формате.</span> $nick=$input {nick}; $color=$input {color}; $send=$input {send}; $exit=$input {exit}; $message=$input {message};
<span class="comment"># Если посетитель нажал кнопку "Отправить".</span> if ($send eq "1") {
<span class="comment"># Проверяем,чтобы поле сообщения не было пустым.</span>
if ($message ne "") {
<span class="comment"># Если все ОК открываем файл на добавление и записываем данные.</span> open (FILE,">>$file"); $string=join (&,$nick,$time,$color,$message); print FILE "$stringn"; close (FILE);
<span class="comment"># Читаем файл в массив и подсчитываем количество сообщений.</span> open (FILE,"$file"); @lines=<FILE>; $count=@lines; close (FILE);
<span class="comment"># Устанавливаем количество сохраняемых сообщений равным 20. # Если этот лимит превышен,первое сообщение удаляется и т.д.</span> if ($count>20) { shift (@lines); }
Вы уже в чате.Добавьте новое сообщение. <вr>Ващ ник-<font color="$color">$nick</font>,цвет-<font color="$color"> $color</font>.</center> <form action="chat.cgi" method="GET"> <input type="hidden" name="action" value="add">
<span class="comment"># Если посетитель не ввел сообщение.</span>
else { print "Content-type:text/htmlnn"; print <<HTML; <html><style> BODY {background-color:#e6e8fa;font-family:arial;font-size:10pt;color:#000080;} </style> <body> <center><h3>Ошибка!</h3> Поле сообщения не должно быть пустым.
<span class="comment">#######################Выход из чата######################### </span>
} else {
<span class="comment"># Записываем сообщение в системный журнал.</span> open (LOG,">>$syslog"); $string="Системное сообщение:$nick вышел из чата $time1"; print LOG "$stringn"; close (LOG);
<span class="comment"># Снова удаляем лишние сообщения.</span> open (LOG,"$syslog"); @strings=<LOG>; $count=@strings; close (LOG); if ($count>10) { shift (@strings); }
<span class="comment"># Перезаписываем файл.</span> open (LOG,">$syslog"); print LOG @strings; close (LOG);
<span class="comment"># Говорим посетителю до свидания :)</span>
print "Content-type:text/htmlnn"; print <<HTML; <html><style> BODY {background-color:#e6e8fa;font-family:arial;font-size:10pt;color:#000080;} </style> <body> <h3 align=center>Спасибо за посещение нашего чата, <font color="0000ff">$nick</font>!</h3>
Заходите еще! <p><center><a href="chat.cgi?action=login">Войти в чат</a></center> HTML
<span class="comment"># Удаляем посетителя из онлайна.Для этого обновляем файл online.txt</span> open (NET,"$online"); @users=<NET>; <span class="comment"># Читаем содержимое</span> foreach $user (@users) { if ($user !~ /$nick/) { <span class="comment"># Сравниваем ник посетителя,выщедшего из чата с каждым # ником в файле и если они не равны помещаем их в массив.</span>
push (@online,$user); } } close (NET);
<span class="comment"># Перезаписываем файл уже без ушедшего посетителя.</span> open (NET,">$online"); print NET @online; close (NET); }
<span class="comment">#Таким образом поддерживается самая свежая информация о посетителях, или я не прав? :))) </span>
Показ посетителей,в данный момент находящихся в чате
<span class="comment">###################### ##Кто в онлайне######################### </span> ($action eq "online") && do {
<span class="comment"># Эта страница также будет обновляться каждые 10 секунд.</span> print "Content-type:text/htmlnn"; print <<HTML;
<html><meta http-equiv="Refresh" content="10"> <style> BODY {background-color:lightsteelblue;font-family:arial;font-size:10pt;} </style> <body>
<span class="comment"># Выводим на экран табличку со смайликами.</span> <p><h5 align=center><font color="000080">Смайлики</font></h5>
<span class="comment"># Отображаем список посетителей.</span> <h5 align=center><font color="000080">Кто в онлайне.</font></h5> HTML
<span class="comment"># Здесь я предусмотрел очистку файла online.txt через 3 минуты после бездействия чата. # Ни к чему хранить давние сообщения. Системный журнал и файл с сообщениями также очищаются # после 3 минут бездействия, как вы увидите дальше.</span>
<span class="comment"># Сравниваем время модификации файла с текущим временем.</span>
<span class="comment"># Если разность более 180 секунд, перезаписываем файл пустым значением.</span> if ($diff3>180) { open (NET,">$online"); print NET ""; close (NET); }
<span class="comment"># Дальше выводим собственно список.</span> open (NET,"$online"); @lines=<NET>; $count=@lines; if ($count!=0) { print "<table bgcolor="e6e8fa" align=center width=80 cellspacing=0 border=1 bordercolor="000000"><tr><td>n"; foreach $line (@lines) { print "<font face="serif" size=2 color="0000ff">",$line,"</font><br>"; } } close (NET); print <<HTML;
</table> <p>
<center><a href="chat.cgi?action=login" target="second">Войти в чат</a></center> HTML
Вывод системного журнала
В системный журнал пишутся сообщения о входе в чат и выходе из него. Он постоянно динамически обновляется. Для вывода его на экран читаем файл syslog.txt
<span class="comment"># Снова проверяем время модификации файла, и если оно больше 180 секунд очищаем его.</span> $cur_time=time; $stat2=(stat ("$syslog"))[9]; $diff2=$cur_time-$stat2;
if ($diff2>180) { open (LOG,">$syslog"); print LOG ""; close (LOG); }
<span class="comment"># Выводим сообщения на экран,начиная с последнего.</span>
open (LOG,"$syslog"); @lines=<LOG>; @strings=reverse @lines; foreach $string (@strings) { print $string,"<br>"; } close (LOG); };
Вывод сообщений
Здесь тоже ничего особенного.Просто выводим сообщения на экран,каждые 10 секунд обновляя его.
<html><meta http-equiv="Refresh" content="10"> <style> BODY {background-color:#e6e8fa;font-family:arial;font-size:10pt;} </style> <body> HTML
<span class="comment"># Файл с сообщениями также очищается после 180 секунд бездействия.</span> $cur_time=time; $stat1=(stat ("$file"))[9]; $diff1=$cur_time-$stat1;
if ($diff1>180) { open (FILE,">$file"); print FILE ""; close (FILE); }
<span class="comment"># Читаем сообщения и выводим на экран, начиная с последнего.</span>
Вот мы и добрались до главной страницы, на которой, собственно, и происходит все это. Она представляет собой набор фреймов, в каждом из которых производятся совершенно независимые действия.