<% ASP на блюдечке %>. Часть 12
Чат своими силами (версия 2)
Создание и подготовка базы данных
Универсальный набор функций (файл utils.asp)
Вход в чат (файл Entrance.asp)
Mодуль добавления новых пользователей в систему (AddUser.asp)
Просмотр списка сообщений чата (файл Text.asp)
Посылка сообщения в чат (файл Chat.asp)
Показ псевдонимов (кто в чате) — файл Nicks.asp
И еще об одной немаловажной проблеме…
Введение
Как мы уже отмечали в предыдущих статьях настоящей серии, тема Интернет-общения актуальна, однако согласитесь, что созданная нами в части 9 настоящей статьи чат-система не лишена недостатков. Наиболее существенным из них является то, что система реализована на базе файловой системы сервера, что, с одной стороны, позволило нам вникнуть в подробности и детально изучить принципы и методы работы с файлами средствами ASP, а с другой — создать достаточно удобный чат-интерфейс, вполне приемлемый для организации общения ограниченного числа пользователей. Однако наверняка читатель заметит проблему, которую таит в себе такой подход, а именно: при возрастании числа пользователей такой системы (транзакционной нагрузки на сервер) обязательно возникнет ситуация, когда файловая система сервера не будет успевать обрабатывать запросы пользовательских страниц, что неизбежно приведет к остановке системы. Именно поэтому в настоящей статье мы продолжим обучение навыкам построения чат-систем и освоим процесс создания базо-основанной, а не файл-основанной чат-системы.
Однако не будем забегать вперед, а попробуем формализовать всю задачу с нуля, с тем чтобы представить себе ее решение максимально детально.
Итак, настоящая статья адресована тем читателям, которые хотели бы самостоятельно разработать с нуля собственную чат-систему.
Что же такое чат?
Настоятельно рекомендую вам задаться этим вопросом, прежде чем продолжать чтение данной статьи.
Как известно, чат — это некая область окна браузера, в которой пользователи могут просматривать текстовые сообщения других пользователей и добавлять свои. Поток сообщений общий, поэтому сообщение, введенное любым пользователем, доступно для всех (хотя существуют чат-системы с возможностью «уединенной» беседы, то есть когда часть сообщений адресована какому-то конкретному пользователю и для остальных пользователей недоступна).
Таким образом, чат представляет собой одномерный поток текстовых сообщений (в отличие от форума, который является двухмерным потоком текстовых сообщений).
Теперь, когда картина нам в общем ясна, предлагаю разобраться с функционалом чат-систем, который, как правило, состоит из следующих функциональных компонентов:
- во-первых, это система идентификации пользователей. Данная система призвана регистрировать имя (псевдоним, nickname), пароль, электронный адрес и т.д. пользователя для обеспечения его уникальности в чат-системе;
- во-вторых, это собственно система представления общего потока текстовых сообщений, позволяющая пользователям просматривать поток текстовых сообщений;
- в-третьих, это система ввода сообщений, формирующая новые сообщения и вставляющая их в общий поток;
- в-четвертых, это система самообновления сообщений с задаваемым определенным интервалом времени.
Этот список можно продолжать, однако, чтобы не усложнять изложение материала, мы не будем этого делать в настоящей статье, а ограничимся лишь наиболее типичными требованиями.
Постановка задачи
С программной точки зрения чат-система должна представлять собой совокупность модулей, каждый из которых предназначен для решения одной из вышеизложенных задач. Таким образом, в состав наиболее типичной чат-системы входят:
- Модуль идентификации пользователей.
- Модуль представления потока сообщений всех пользователей.
- Модуль представления имен (псевдонимов) всех подключенных пользователей.
- Модуль формирования и ввода новых сообщений.
Структура приложения
Однако прежде чем приступать к созданию базо-основанного чата, давайте представим себе, каким же образом будет осуществляться обмен сообщениями — ведь в качестве носителя данных у нас теперь выступают не файлы на жестком диске сервера, а база данных. Да очень просто: все текстовые сообщения, предварительно обрамленные в необходимые HTML-тэги форматирования, будут «складываться» в определенную таблицу базы данных, после чего будет генерироваться страница на основе этой таблицы, которая будет доступна всем пользователям нашего чата. Аналогичные действия необходимо проделать и со страницей псевдонимов, которая, в свою очередь, будет генерироваться на основании таблицы пользователей.
Что нам понадобится
Конечно же, предполагается, что читатель знаком с основами ASP- и SQL-программирования (первых частей настоящей статьи для этого будет вполне достаточно). Кроме того, нам потребуется Microsoft SQL Server 7.0 или 2000, какой-нибудь HTML- или текстовый редактор (рекомендую использовать Macromedia Dreamweaver UltraDev 4.0) и немного терпения.
Создание и подготовка базы данных
Создадим две таблицы: таблицу пользователей (ChatUsers) и таблицу сообщений (Chat). Представим себе их взаимосвязь так, как показано на рисунке.
Ключевыми здесь являются столбцы UserID. Их взаимосвязь, по сути, отражает взаимосвязь сообщений и их авторов. Теперь, когда база данных готова, можно переходить к созданию самого форума.
Однако прежде следует уяснить вопрос, каким именно образом будет отслеживаться состояние пользователей, находящихся в режиме онлайн? Для этого в таблице пользователей необходимо предусмотреть соответствующую галочку (поле). Таким образом, выполняя соответствующий запрос к таблице пользователей, можно будет выяснить, кто из пользователей находится в режиме онлайн.
Универсальный набор функций (файл utils.asp)
Прежде чем приступить непосредственно к разработке нашего чата, вынесем все многократно используемые типовые функции в один файл, который впоследствии по мере необходимости будем «включать» в разрабатываемые странички. Разберемся, что нам для этого понадобится. Прежде всего это функции соединения и закрытия соединения с базой данных:
<% @ LANGUAGE="VBSCRIPT" %>
<% Option Explicit %>
<!--#include file="cdovbs.inc"-->
<%
option explicit
Response.Buffer = true
'***** Строим строку соединения с базой данных ***************************
dim Dsn, Conn, Rs, sSQL
Dsn = "DSN=Chat; UID=sa;PWD=;database=Chat"
'**** Подсоединяемся к базе данных форума ********************************
Sub Connect()
set conn = server.createobject("adodb.connection")
set rs = server.createobject("adodb.recordset")
conn.open Dsn
End Sub
'**** Закрываем соединение с базой данных форума *************************
Sub Close()
Rs.close
set Rs = nothing
Conn.close
set Conn = nothing
End Sub
%>
Вход в чат (файл Entrance.asp)
Главная страница чата предназначена для выбора пользователем имени-псевдонима и пароля, указания им предпочтительного цвета имени, а также для нескольких настроек: количества одновременно отображаемых сообщений и времени обновления текстовой страницы в секундах.
<!--#include file="utils.asp"-->
<SCRIPT LANGUAGE = VBScript RUNAT=Server>
<!-- Metadata type="typelib" File="c:\program files\common files\system\ado\msado15.dll" -->
</SCRIPT>
<%
Dim IName, Passwd, Msg, CurUser, Odd, NameNum, db, IsError, TextStr, Str
Iname = Request.Form("nickname")
Passwd = Request.Form("passwd")
If IName = "" Then
msg = "Вы не ввели логин пользователя!"
IsError = True
Else
If Passwd = "" Then
msg = "Вы не ввели пароль пользователя!"
IsError = True
End If
If InStr(IName,"<") < 1 Then
Call Connect
sSQL = "SELECT * FROM ChatUsers WHERE UserNickName = '" & Iname & "' AND UserPassword = '" & Passwd & "'"
Rs.open sSQL, Conn
If rs.Eof Then
IsError = True
msg = "<font color='red'>Вы ошиблись при вводе имени пользователя и/или пароля.</font>"
End If
If Not IsError Then
IsError = False
Session("UserID") = Rs.Fields("UserID").value
Session("UserName") = Iname
Session("UserColor") = Request("user_color")
Session("RefreshTime") = Request("RefreshTime")
Session("LNum") = Request("LNum")
TextStr = "<table><tr><td><B><font color='" & Session("UserColor") &"'>" & _
Session("UserName") & "</font></B>" &_
" : " & "вошел в чат - " & date & " " & time & "</td></tr></table>"
Call Close()
Call Connect()
sSQL = "SELECT * FROM Chat"
RS.Open sSQL, Conn, 3, adLockOptimistic
rs.AddNew
rs("UserID") = 0
rs("DateSaid") = Now()
rs("Said") = TextStr
rs.Update
Call Close()
Call Connect()
sSQL = "UPDATE ChatUsers Set IsOnLine = 1, UserColor = '" & Session("UserColor") &_
"' WHERE UserNickName = '" & Iname & "' AND UserPassword = '" & Passwd & "'"
Conn.Execute(sSQL)
Conn.close
set Conn = nothing
Response.Redirect("MainFS.asp")
End If
IsError = false
Call Close
End If
End If
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
</head>
<body bgcolor="#D7D5C0" text="#000000" link="#000000" vlink="#FFFFFF" alink="#FFFFFF">
<BR><BR><BR>
<center>
<font color="#000000" size=+2>Добро пожаловать в Чат</font>
</center>
<BR>
<center>
<p>Сейчас в чате:</p>
<table align= "center" width= 400 border = 0>
<tr><td align= "center">
<%
CurUser = 0
Odd = 0
NameNum = 0
Call Connect
sSQL = "SELECT * FROM ChatUsers WHERE IsOnline = 1"
Rs.open sSQL, Conn
Do While Not rs.EOF
If Odd = 0 Then
If NameNum = 10 Then
Response.Write "</td></tr><tr><td align= 'center'>"
NameNum = 0
End If
Str = Rs.Fields("UserNickName").value
If Str <> "" Then
Response.Write "[" & Str & "] "
Odd = 1
CurUser = CurUser + 1
NameNum = NameNum + 1
End If
Else
Odd = 0
Rs.MoveNext
End If
Loop
If CurUser = 0 Then
Response.Write "нет пользователей"
Else
Response.Write "</td></tr><tr><td align= 'center'>Всего " & CurUser
End If
Call Close
%>
</td></tr></table>
<br>
<Form name="Nickname" method="post" action="Entrance.asp">
<table width= 400 border = 1>
<tr>
<td>Ваш псевдоним:</td>
<td><input type=text name="nickname" value="" style="font: 8pt 'Verdana'; background-color: #FCFBE8;"></td>
</tr>
<tr>
<td>Ваш пароль:</td>
<td><input type=password name="passwd" value="" style="font: 8pt 'Verdana'; background-color: #FCFBE8;"></td>
</tr>
<tr>
<td></td><td><a href = "Newuser.asp">Новый пользователь?</a></td>
</tr>
<tr>
<td valign="top">Ваш цвет:</td>
<td>
<FONT FACE="arial, verdana, helvetica" SIZE="2">
…
Группа переключателей (радиокнопок) для выбора цвета.
…
</FONT>
</td>
</tr>
<tr>
<TD>Обновление чата:</TD>
<TD><SELECT NAME="RefreshTime" style="font: 8pt 'Verdana'; background-color: #FCFBE8;">
<OPTION VALUE="5">5
<OPTION VALUE="10"Selected>10
<OPTION VALUE="15">15
<OPTION VALUE="20">20
<OPTION VALUE="30">30
<OPTION VALUE="60">60
</SELECT> секунд
</TD>
</tr>
<tr>
<td>Просматриваемых сообщений:</td>
<td><INPUT TYPE="text" NAME="LNum" VALUE="30" SIZE="2" MAXLENGTH="2" style="font: 8pt 'Verdana'; background-color: #FCFBE8;"></td>
</tr>
</table>
<br>
<input type=submit name="okbtn" value="Войти"
</Form>
<BR><H6><%=msg%><br>Использование HTML-тэгов недопустимо!</h6><BR>
</center>
</body>
</html>
Вход в чат впервые
Далее система попытается найти указанного пользователя в таблице пользователей, и если ей это не удастся, то пользователь не будет допущен в чат. Для «вновь прибывших» пользователей следует предусмотреть механизм регистрации в системе, форму регистрации с проверкой введенных значений на допустимые диапазоны и типы, а также модуль добавления новых пользователей в систему:
Форма регистрации для новых пользователей (файл NewUser.asp):
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>чат (регистрационная форма)</title>
<SCRIPT TYPE="text/javascript" SRC="script.js">
<!-- // displays only if script file not found
document.write ("JavaScript library not found.");
//-->
</SCRIPT>
<SCRIPT TYPE="text/javascript">
<!--
function checkMe() {
var ok;
with (document.EOForm){
if ( isBlank(Nick, 'Введите Ваш псевдоним.')) return false;
if ( isBlank(Name, 'Введите Ваше имя.')) return false;
if ( !PasswordCheck(Password, repPassword)) return false;
if ( isBlank(Email,'Введите адрес электронной почты')) return false;
if (!isEmail(Email,'Введите адрес электронной почты в правильном формате (например, somebody@domain.ru)')) return false;
if (!isIntegerValue(UIN,'Введите правильно Ваш номер ICQ.')) return false;
}
return true;
}
//-->
</SCRIPT>
</head>
<body bgcolor="#D7D5C0" text="#000000" link="#000000" vlink="#FFFFFF" alink="#FFFFFF">
<table align = "center" width="570" border="0" cellspacing="0" cellpadding="0"><tr><td>
<div align="center">
<p><b>Пожалуйста, заполните эту форму для получения доступа в чат:</b></p>
<Form name = "EOForm" Method="get" Action = "AddUser.asp" onSubmit="return checkMe();">
<table width="470" border="0" cellspacing="3" cellpadding="0">
<tr><td>Ваш псевдоним (nickname) (*):</td>
<td><Input Type="text" Name="Nick" Size="30" style="font: 8pt 'Verdana'; background-color: #FCFBE8;"></td>
</tr>
<tr><td>Ваше имя(*):</td>
<td><Input Type="text" Name="Name" Size="30" style="font: 8pt 'Verdana'; background-color: #FCFBE8;"></td>
</tr>
<tr><td>Ваш пароль(*):</td>
<td><Input Type="password" Name="Password" Size="30" style="font: 8pt 'Verdana'; background-color: #FCFBE8;"></td>
</tr>
<tr><td>Повторите пароль(*):</td>
<td><Input Type="password" Name="repPassword" Size="30" style="font: 8pt 'Verdana'; background-color: #FCFBE8;"></td>
</tr>
<tr>
<td>Ваш электронный адрес(*):</td>
<td><Input Type="text" Name="Email" Size="30" style="font: 8pt 'Verdana'; background-color: #FCFBE8;"></td>
</tr>
<tr>
<td>Ваш URL:</td>
<td><Input Type="text" Name="URL" Size="30" style="font: 8pt 'Verdana'; background-color: #FCFBE8;"></Input></td>
</tr>
<tr>
<td>Ваш номер ICQ:</td>
<td><Input Type="text" Name="UIN" Size="30" style="font: 8pt 'Verdana'; background-color: #FCFBE8;"></Input></td>
</tr>
<tr>
<td>Другая информация:<BR></td>
<td><textarea Type="text" Name="Info" cols="29" rows="5" Size="30" style="font: 8pt 'Verdana'; background-color: #FCFBE8;"></textarea></td>
</tr>
</table>
<br>
<Input Type="submit" style="WIDTH: 150px" Value="Подтверждаю">
<input type="reset" style="WIDTH: 150px" value="Очистить" name="Reset">
</form>
</div>
</td></tr>
</table>
</body>
</html>
Проверка корректности введенных пользователем значений полей формы реализуется путем вызова ряда JavaScript-функций проверки из библиотеки script.js. Однако мы не будем останавливаться на всех этих функциях подробно, так как мы делали это в одной из предыдущих статей настоящей серии.
Mодуль добавления новых пользователей в систему (AddUser.asp)
<!--#include file="utils.asp"-->
<SCRIPT LANGUAGE = VBScript RUNAT=Server>
<!-- Metadata type="typelib" File="c:\program files\common files\system\ado\msado15.dll" -->
</SCRIPT>
<%
Call Connect()
sSQL = "SELECT * FROM ChatUsers"
RS.Open sSQL, Conn, 3, adLockOptimistic
rs.AddNew
rs("UserNickName") = request("Nick")
rs("UserName") = request("Name")
rs("UserPassword") = request("Password")
rs("UserMail") = request("EMail")
rs("UserURL") = request("URL")
rs("UserUIN") = request("UIN")
rs("UserInfo") = request("Info")
rs("IsOnLine") = False
rs.Update
Call Close()
Response.Redirect "Entrance.asp"
%>








