我们要建设一个聊天室,首先,这个聊天室的整体概况要在我们脑海中要有一个初步的影像,在众多的公共聊天室中,其核心无非是:
1、聊天者把语句写入文本或数据库;
2、浏览器不断的对文本或数据库进行刷新、读取;
3、实时更新在线的客户;
4、治理员对聊天者进行踢或IP禁止操作。 若是一个初学程式设计,你能够实现写数据库、自动刷新、获取客户IP的实验,那么,实际上建设聊天室也就完成了一大半。首先,要完成这几个实验,我们至少要熟悉一些ASP脚本及一些SQL命令。
1、
<%IP=Request("REMOTE_ADDR")%>
您的IP地址为:
<%=IP%>
这是一段获取客户IP的脚本,假如你看过《ASP教程》,你应该知道REMOTE_ADDR是
一个服务器环境变量,返回发出请求的远程主机(client)的IP地址。
2、
<%
Set Conn=Server.CreateObject("ADODB.Connection")
Connstr="DBQ="+server.mappath("chat.mdb")+";DRIVER={Microsoft Access Driver (*.mdb)
};" Conn.Open connstr
sql="SELECT * FROM 在线用户表 WHERE 姓名=''''''''" & Request("name") & "''''''''"
Set Rs=conn.Execute(sql) If Rs.Bof OR Rs.Eof Then
sz = "''''''''" & Request("name") &_
"'''''''', ''''''''"& Request("D4") &_
"'''''''', ''''''''"& time1 & "''''''''"
into_db = "INSERT INTO 在线用户表 ( 姓名, 性别, 登陆时间 ) VALUES(" &_
sz & ")"
conn.Execute(into_db)
end if
%>
这是一段十分常见的对数据库操作的脚本,其中包含了对数据库的条件查询与记录添加。上面此段程序我们分三部分来分析,如上以空格分隔的三个部分。
要使用组件提供的对象,请创建对象的实例并将这个新的实例分配变量名。使用ASP的Server.
CreateObject方法可以创建对象的实例,使用脚本语言的变量分配指令可以为对象实例命名,如下例:
Set Conn=Server.CreateObject("ADODB.Connection")
这里的变量Conn 是ASP 程序创建的访问数据库的对象实例 。
我们要访问数据库,首先要必须知道这个数据库在哪里,这个数据库的驱动程序是什么,要指定这两点有两种方法:第一是在服务器端手动创建数据库源名、指定数据库路径、指定数据库驱动程序,这个方法是通过服务器端的控制面版中的 ODBC 来设置的。她的优点是可以限定数据库的访问权限,增加数据库的安全性,缺点是数据库不易移植。
再有一种方法是使用 ASP 来指定数据库路径及数据库驱动程序。不必手动对创建数据库源。在此例中,我们用的是第二种方法。
server.mappath("chat.mdb")指定数据库路径,DRIVER={Microsoft Access Driver
(*.mdb)};
指定数据库驱动程序,此例中我们使用的是MS ACCESS 数据库。
SELECT是 SQL 查询命令。sql="SELECT * FROM 在线用户表 WHERE 姓名=''''''''" & Request("name") & "''''''''" 表示查询 数据库chat.mdb中的 在线用户表 中所有姓名等于Request("name")的人,Request("name")是读取表单中名为 NAME 的数据。
Bof 是文件开头,Eof是文件结尾。If Rs.Bof OR Rs.Eof Then...语句往往用于判定数据库中是否存在符合条件的记录,假如为真则记录不存在,假如为假则记录存在。
INSERT INTO是SQL中的插入命令,往往用于插入一条记录。
上面此段程序,整体的意思就是:查询数据库在线用户表中是否存在用户Request("name"),假如不存在这个用户则把这个用户添加到在线用户表中。
3、
<meta http-equiv="refresh" content="4">
这是一条最简单的页面自动刷新脚本,她是HTML脚本,而不是ASP脚本。很简单吧,其意思是每4秒钟刷新一次,但在使用过程中,你会发现会出现有不少问题出现。接下来,我们开始讲述建设过程,首先,我们要规划,要大概了解使用多少个数据库表,这些数据库表应该有哪些字段;摆在我们面前的就已经是必须存在的几个数据库表:1、存储用户信息的用户表,2、存储发言信息的发言表,3、存储在线用户信息的在线用户表等。
建议使用ACCESS或SQL SERVER 数据库,建立一个ACCESS数据库实在是太简单了,就象建立一个EXCEL表格差不多,你可以不必了解太多的数据库知识。
我们先建立chat.mdb数据库包含用户表及聊天表:如下:
用户表:
ID IP 姓名 性别 密码
. . . . .
. . . . .
聊天表:
ID IP 姓名 颜色 表情 说话对象 说话
. . . . . . .
. . . . . . .
在线用户表:
ID 姓名 性别 登陆时间
. . . .
. . . .
数据库一旦建立,我们便可以开始着手编程,首先要考虑建立如下几个独立文件:1、登陆及发言区;2、刷新区;3、治理区。
先来看登陆及发言区:这是聊天室的核心部分,请先看看流程: 登陆<———————————|
| |
| |
获取用户名、用户IP、密码 |
| |
| |
| |
| 密码错误 |
|——————————查询用户表——————————|
| 密码正确 |
| |
| 初|
| 次|
| 登|
| 陆|
| |
| |
| 把用户名、用户IP、及密码写入用户表
| |
| |
|————>把用户名、登陆时间写入在线用户表
|
|
|—————————-—>发言区
| |
| |
| 选|选
| 择|择
| 颜|说
| 色|话
| 与|的
| 表|对
| 情|象
| |
| |
| 发言
| |
| |
| 把姓名、说话内容、说话对象、
| 颜色、表情写入聊天表
| |
| |
| 发言 | 离开
|-————————————|————————————|
|
|
|
|<-———————————|
|
|
从在线用户表中删除该用户
|
|
|
离开聊天室
接下来,我们开始对用户登陆与发言实例程序进行分析:chatadd1.asp
1、用户登陆
<%Response.Buffer=true%> 指定缓存为真
<body bgcolor="#F8E17A">
<%if Request("name")="" then%> 判定用户名是否为空,以判定用户是否在聊天
界面
<%addr=Request("REMOTE_ADDR")%> 获得用户IP
<form method="POST" action="chatadd1.asp">
<p><input type="hidden" name="IP" value="<%=addr%>"><p> 用户登陆表单
<p>请输入匿名:<input type="text" name="name" size="15">
密码:<input type="password" name="pass" size="15"> 性别:<select name="D4" size="1" style="color: rgb(0,0,128)">
<option value="先生">先生</option>
<option value="女士">女士</option>
</select> <input type="submit" value="发送" name="B1">
<input type="reset" value="复原" name="B2"></p>
</form>
<%=Request("a")%> 返回的错误变量
<%else%> 用户确在聊天界面中 <%B1=Request("B1")
If B1="发送" Then 开始判定用户名与密码 If Request("name")="" or Request("pass")="" Then 判定用户名与密码是否为空
a="名字或密码不能为空!<br>" 假如为空,则定义此错误变量
Response.Redirect "chatadd1.asp?a=" & a & " " 错误一旦出现立即返回登陆界面
end if Set Conn=Server.CreateObject("ADODB.Connection") 假如客户输入非空,则开始查询数据库
Connstr="DBQ="+server.mappath("chat.mdb")+";DRIVER={Microsoft Access Driver (*.mdb)};"
Conn.Open connstr
sql="SELECT * FROM 用户表 WHERE 姓名=''''''''" & Request("name") & "''''''''" 查看数据库中是否存在这个用户
Set Rs=conn.Execute(sql)
If Rs.Bof OR Rs.Eof Then 假如数据库中还没有这个用户,则
sz = "''''''''" & Request("IP") &_ 把该用户写入用户数据库
"'''''''', ''''''''"& Request("name") &_
"'''''''', ''''''''"& Request("D4") &_
"'''''''', ''''''''"& Request("pass") & "''''''''"
into_db = "INSERT INTO 用户表 ( IP, 姓名, 性别, 密码 ) VALUES(" &_ 写入用户数据库
sz & ")"
conn.Execute(into_db) Else 假如数据库中已经存在这个用户,则
If Request("pass")<>Rs("密码") Then 查看他的密码是否正确。
a="这个名字已经被别人使用,或者你输入的口令不对!<br>" 假如密码错误则定义错误信息
Response.Redirect "chatadd1.asp?a=" & a & " " 立即返回登陆界面并返回此错误信息
end if
end if
time1=now 假如登陆表单没有任何错误,则开始成为在线用户并进
入聊天
Set Conn=Server.CreateObject("ADODB.Connection")
Connstr="DBQ="+server.mappath("chat.mdb")+";DRIVER={Microsoft Access Driver (*.mdb)};"
Conn.Open connstr
sql="SELECT * FROM 在线用户表 WHERE 姓名=''''''''" & Request("name") & "''''''''" 查看在线名单中是否存在这
个用户
Set Rs=conn.Execute(sql)
If Rs.Bof OR Rs.Eof Then 假如在线名单中的确没有这个用户,则
sz = "''''''''" & Request("name") &_ 在在线用户表中添加这个用户
"'''''''', ''''''''"& Request("D4") &_
"'''''''', ''''''''"& time1 & "''''''''"
into_db = "INSERT INTO 在线用户表 ( 姓名, 性别, 登陆时间 ) VALUES(" &_ 添加这个用户
sz & ")"
conn.Execute(into_db) name=Request("name")
sex=Request("D4")
ming="治理员公布" 治理员开始公布欢迎这位(先生/女士)
的光临
sz="<font size=5 color=#FF0000><strong>" & "热烈欢迎" & name & sex & "的光临"
into_db2 = "INSERT INTO 聊天表 ( 姓名,说话 ) VALUES(''''''''" & ming & "'''''''',''''''''" & sz & "'''''''')"
conn.Execute(into_db2) end if end if%>
2、用户发言
用户开始真正发言
<%addr=Request("REMOTE_ADDR")%> 用户IP
<form method="POST" action="chatadd1.asp"> 用户发言表单
<p><input type="hidden" name="ip" value="<%=addr%>"><p>
<p><input type="hidden" name="name" value="<%=Request("name")%>"><p>
<p><input type="text" name="word" size="70"><input type="submit" value="发言" name="B3"><input
type="reset" value="复原" name="B4"> <p>颜色:<select name="D1" size="1" style="color: rgb(0,0,128)">
<option value=" ">黑色</option> 颜色选择
<option value="#ff0000">红色</option>
<option value="#008000">绿色</option>
<option value="#0000FF">蓝色</option>
<option value="#800080">紫色</option>
<option value="#008080">青色</option>
<option value="#800000">深红色</option>
<option value="#00ff00">草绿色</option>
<option value="#00ffff">海蓝色</option>
</select> <%
Set Conn=Server.CreateObject("ADODB.Connection") 查询更新在线用户
Connstr="DBQ="+server.mappath("chat.mdb")+";DRIVER={Microsoft Access Driver (*.mdb)};"
Conn.Open connstr
sql="SELECT * FROM 在线用户表 "
Set Rs=conn.Execute(sql)
%> 对象:<select name="D2" size="1" style="color: rgb(0,0,128)"> 从在线用户中选择说话对象
<option value="大家">大家</option>
<%Do While not Rs.Eof 在线用户表单
if Rs("姓名")=Request("D2") then
s="selected" 这里的条件定义s是为了保持说话对象的不变性,
else 使用户不必每次都选择说话对象,你也可以对颜色
s="" 与表情如法炮制。
end if%>
<option <%=s%> value="<%=Rs("姓名")%>"><%=Rs("姓名")%>(<%=Rs("性别")%>)</option>
<%
Rs.MoveNext
Loop
%>
</select>
表情:<select name="D3" size="1" style="color: rgb(0,0,128)"> 表情选择
<option value="微笑着对">微笑</option>
<option value="大笑着对">大笑</option>
<option value="哭泣着对">哭泣</option>
<option value="害羞着对">害羞</option>
<option value="红着脸对">脸红</option>
<option value="愤怒的对">愤怒</option>
<option value="阴沉的对">阴沉</option>
<option value="奸笑着对">奸笑</option>
</select>
<input type="submit" value="离开聊天室" name="B5">
<a href="admin.asp">治理员入口</a>
</form>
<%
B3=Request("B3")
If B3="发言" Then 预备把用户发言写到聊天表中
Set Conn=Server.CreateObject("ADODB.Connection")
Connstr="DBQ="+server.mappath("chat.mdb")+";DRIVER={Microsoft Access Driver (*.mdb)};"
Conn.Open connstr
%> <%
word=Request("word")
if Request("word")="" then 假如什么都没写就发言,则默认发言为两眼开开,正在发呆
word="两眼开开,正在发呆....."
end if
%> <%
sz = "''''''''" & Request("ip") &_ 把用户发言写到聊天表中
"'''''''', ''''''''"& Request("name") &_
"'''''''', ''''''''"& Request("D1") &_
"'''''''', ''''''''"& Request("D3") &_
"'''''''', ''''''''"& Request("D2") &_
"'''''''', ''''''''"& word & "''''''''"
into_db = "INSERT INTO 聊天表 ( ip, 姓名, 颜色, 表情, 说话对象, 说话 ) VALUES(" &_
sz & ")"
conn.Execute(into_db)
conn.Close end if
3、用户离开
B5=Request("B5")
If B5="离开聊天室" Then 假如用户选择离开聊天室则
Set Conn=Server.CreateObject("ADODB.Connection")
Connstr="DBQ="+server.mappath("chat.mdb")+";DRIVER={Microsoft Access Driver (*.mdb)};"
Conn.Open connstr 从在线名单中把他删除
sql5="delete * FROM 在线用户表 WHERE 姓名=''''''''" & Request("name") & "''''''''"
conn.Execute(sql5) name1=Request("name")
sex1=Request("D4")
ming1="治理员公布" 治理员公布此用户离开
sz1="<font size=5 color=#FF0000><strong>" & name1 & sex1 & "有事先离开,欢迎再来"
into_db2 = "INSERT INTO 聊天表 ( 姓名,说话 ) VALUES(''''''''" & ming1 & "'''''''',''''''''" & sz1 & "'''''''')"
conn.Execute(into_db2)
conn.close
Response.Redirect "chat.asp"
end if end if
%>
把此文件存为chatadd1.asp 当我们把上面的程序保存在具有执行权限的服务器目录中,在客户端用浏览器打开时,我们见到了平常聊天室一样的用户登陆界面。我们于是输入用户名及密码,按发送时,我们所输入的资料便会暗中存入用户数据库中。接着便出现了发言筐,我们试着输入一句话,点发言按钮,这时,我们的发言便会带着我们所输入的话,我们所选择的说话对象,我们所选择的颜色以及表情写入发言数据库中。但是,发言之后,我们并没有发现任何语句出现在屏幕上,那是因为:这个程序本身负责的纯粹是把数据库写入数据库,他不会向客户端返回任何东西,除非你的输入是错误的。
聊天室还需要一个重要的程序,这个程序自动的、不断的读取数据库中最新的记录,把他显示在所有用户的浏览器上。这个程序与别的任何程序没有任何关系,他的唯一的任务是读取发言数据库中的数据,把他显示出来,他不管客户是否输入发言,不管客户对谁说话,不管客户选择什么表情与颜色。当这个聊天室即使没有一个人说话,这个程序也是不断的读取这个数据库,每N秒钟刷新一次,这个N是由编程者决定的。
由此,我们可知:登陆_发言部分与自动刷新部分是没有任何联系的。
在分析范例程序之前,我们最好来分析一下几点:
1、在我们往数据库中写入数据库时,记录是不断往数据表的尾部增加的,因此,我们必须知道哪一句话是新的,哪一句话在前面说的,我们知道,在MSACCESS数据库表中,有一个自动编号的字段ID,这个字段非常有用,ID最大的记录是最新输入的记录,每添加一个记录,ID自动加1,由此,我们可通过ID来对用户的话进行从新到旧的、一句一句的排序输出。我们知道,在 SQL 的SELECT 语中有一个 ORDER BY的子句,他按一列或多列对结果进行升序或降序排序。假如我们不用ORDER BY 字句,那SELECT 默认为升序输出,那我们会看到,最旧的发言总是在前面显示,而最新的语句则跑到最后面去,那当然不是我们所希望的。
2、再一点,那就是用户不断的往数据库中输入语句,数据库将会变得越来越大,而我们为了速度,我们不能也不必要读取全部的记录把所有的话显示出来,我们只需要看到最新的N句话比如最新的50句话就够了。如何实现上面两点,且来看看范例程序:
我们来分析一下下面的程序:
chatview.asp <%Response.Buffer=true%> 设置缓存为真 <% 指定数据库
Set Conn=Server.CreateObject("ADODB.Connection")
Connstr="DBQ="+server.mappath("chat.mdb")+";DRIVER={Microsoft Access Driver (*.mdb)};"
Conn.Open connstr
%> <%
sql="SELECT * FROM 聊天表 ORDER BY ID DESC" 降序输出查询结果
Set rootRs=conn.Execute(sql)
set name=rootrs("姓名") 从数据库中获取姓名、说话、颜色、表情等
set word=rootrs("说话")
set colo=rootrs("颜色")
set face=rootrs("表情")
set who=rootrs("说话对象")
%> <%i=0%> 定义输出记录数 i
<%Do While Not rootRs.Eof and i<=50%> 显示50句话,包括姓名、话语、颜色、表情等
<%i=i+1%>
<table border=''''''''0'''''''' cellpadding=''''''''0'''''''' cellspacing=''''''''0'''''''' width=''''''''85%''''''''><tr>
<td width=''''''''100%'''''''' bgcolor=''''''''#C0C0C0''''''''></td></tr><tr><td width=''''''''100%''''''''>
<font color=''''''''#0000FF''''''''><strong><%=name%></font></strong><font color=''''''''#008080''''''''><%=face%></font><font color=''''''''#0000FF''''''''><strong><%=who%>说:
</font></strong><font color=''''''''<%=colo%>''''''''><%=word%>
</font></td></tr><tr>
<td width=''''''''100%'''''''' bgcolor=''''''''#C0C0C0''''''''></td></tr></table><br>
<%rootRs.MoveNext
Loop%> <meta http-equiv="refresh" content="4"> 每四秒钟刷新一次
请把此程序存为chatview.asp 我们试着在客户端用浏览器打开chatview.asp,我们果然看到自动刷新的页面,不错吧!下面,我们就要考虑如何把发言部分与刷新部分在同一个页面上显示:那需要用到框架。
框架,那是最简单不过的了,直接用Frontpage即可构建。请看如下代码:
<frameset rows="*,90" frameborder="0">
<frame name="main" scrolling="yes" src="chatview.asp">
<frame name="footer" scrolling="yes" noresize target="main" src="chatadd1.asp">
<noframes>
<body>
<p>This page uses frames, but your browser doesn''''''''t support them.</p>
</body>
</noframes>
</frameset>
请把这个程序存为chat.asp
哈哈,现在,我们在客户端输入:
http://XXX.XXX/chat.asp于是,便可以开始聊天了!
当很多人进入聊天室,把大量的话写入了我们的数据库中,于是,我们的数据库越来越大,记录越来越多,
而ACCESS数据库大小是有限制的,因此,总会有崩溃的一天,由此,我们必须使数据库大到一定程度的时候自动提醒我们,让我们删除掉比较旧的N条话语。或者让数据库自动到某一定大小时自动删除部分记录。
当一些不文明之徒进入聊天室,发布一些反动言论,我们必须把他踢掉,或者禁止他的IP,禁止N个钟头,尚或把他的IP列入黑名单,让他永远无法进入。