<p align="left"><font id="zoom">1 页面登陆的基本要素<br>你可以在我的竹叶看到登陆 的表单,这里提供了最基本的登陆表单项<br>(1)登陆表单<br> <form onsubmit="b1_submit();return true;" action="chat/login.php?action=enter" method="post" target="howtodo" name="[object]"> <br>(a)聊天表单的名字为chatform,我使用action=enter作为进入聊天室的入口,如果没有这个参数,则显示登陆页 面.<br>(b)在表单提交时,先调用b1_submit()建立聊天的窗口<br>(c)聊天的目标窗口为b1_submit()建立 的howtodo窗口<br><br>(2)表单项<br>昵称:<input maxlength="10" size="15" name="name"><br>密码:<input type="password" maxlength="10" size="15" name="pass"><br><input style="WIDTH: 100px" type="submit" name="submit" value="登陆"><br><input style="WIDTH: 50px" type="reset" name="reset" value="重添"><br>(a)各表单项一定要设定最大允许长度 maxlength<br><br>(3)建立聊天窗口的js<br> language="javascript" type="text/javascript"><br>function b1_submit(){<br>chat=window.open('',"howtodo",'Status=no,scrollbars=no,resizable=no');<br>chat.moveTo(0,0);<br>chat.resizeTo(screen.availWidth,screen.availHeight);<br>chat.outerWidth=screen.availWidth;<br>chat.outerHeight=screen.availHeight;<br>}<br>这段代码先 打开一个没有状态栏,滚动条,可调整尺寸的howtodo窗口!然后移动到屏幕左上角,然后放大到允许的屏幕大小. <br><br>聊天室编程思想--大门 -- 通行证<br><br>大门 -- 通行证<br>聊天室可以采用完全自由的方式运行,你可以随意 输入呢称,不用密码,不保存你的聊天状态,优点是:自由,非常适合于游客!另外一个方法是注册聊天室,每个进入 聊天室的人都要输入自己的用户名和密码才能进入!优点:充分体现个性,非常适合于老朋友,他们的呢称不会被 人恶意侵占使用.我的聊天室使用注册方法!<br><br>注册通常采用2种方法:1,先注册然后进入聊天;2,自动注 册,然后在里面修改自己的资料!我采用第2种方法!!每个新进入的聊友的用户名会被自动保存到注册到数据库内 ,下次登陆必须输入准确的密码才能进入!<br><br>下面是判断部分!本程序使用文本数据库 !<br><br>//$useronline为在线人的数据文件名称<br>//$useronlinelock为在线人的锁定标志 <br>//$register为已经注册的数据文件名称<br>//$registerlock为注册文件的锁定标志<br>//$split为分隔 符<br><br>//登陆参数 enter<br>if($action == "enter")<br>{<br>//当前时间秒数<br>$timecurrent = date("U");<br><br>//锁定在线人数文件,防止同时修改同一个文件<br>while( file_exists($useronlinelock))<br>{<br>if(!file_exists($useronlinelock))<br>{<br>break;<br>}<br>}<br><br>//创建临时文件 <br>fclose(fopen($useronlinelock,"w"));<br><br>//读入在线用户和已经注册用户的信息:密码,昵称,更新时间 <br>$useronline = file($useronline);<br>$register = file($register);<br><br>//用于判断登 陆是否成功的标志<br>$namesign=0;<br><br>//判断用户名,密码的错误,用户名不允许为空,不允许超过10 个字符,密码不允许超过20个字符<br>if(($name =="") || (strlen($name) > 10) || (strlen($pass) > 20) )<br>{<br>print("没有昵称或密码过长");<br>//登陆失败<br>$namesign=1;<br>//删除临时文件<br>unlink($useronlinelock);<br>} <br>else<br>{<br>//查找是否已经有人注册或者密码错误<br>$foundsign=0;<br>for($i=0;$i<count>{<br>//分割<br>$tempregister = split($split,$register[$i],99);<br>//找到已经注册的用户名<br>if( $name == $tempregister[0] )<br>{<br>//已经找到标志<br>$foundsign=1;<br>//密码正确吗<br>if($pass != $tempregister[1])<br>print("密码错了!");<br>//登陆失败<br>$namesign=1;<br>unlink($useronlinelock);<br>break;<br>}<br>else<br>{<br>//老用户登陆成功<br>$namesign=0;<br>break;<br>}<br>}<br><br>}<br><br>//如果没有找到这个用户名,那么就自动注册 <br>if(!$foundsign)<br>{<br>//保存用户名和密码<br>$handle = fopen($register,"a");<br>fputs($handle,"$name$split$pass$split ");<br>fclose($handle);<br>//新 用户登陆成功<br>$namesign=0;<br>}<br>}<br>}<br>if(!$namesign)<br>{ <br>//更新在线人的名单<br>$useronlinehandle = fopen($useronline,"w");<br><br>//判断是否已经在里面,只是刷新页面<br>$updatesign = 0;<br>for($i=0;$i<count>{<br>$usertemp=split($split,chop($useronline[$i]),99);<br>if($name == $usertemp[0])<br>{<br>//更新标志<br>$updatesign = 1;<br>fputs($useronlinehandle,$useronline[$i]);<br>}<br>else<br>{<br>fputs($useronlinehandle,$useronline[$i]);<br>}<br>}<br>//如 果没有在里面,则增加到里面<br>if(!$updatesign)<br>fputs($useronlinehandle,"$name$split$level$split$pass$split$timecurrent ");<br>fclose($useronlinehandle);<br><br>//去掉缩定<br>unlink($useronlinelock);<br><br>//登陆成 功<br>}<br><br>到这里,用户的验证已经完成,聊友已经合法的进入了聊天室,携带者呢称和密码 <br><br><br>聊天室编程思想--大厅 -- 显示界面<br><br><br>大厅 -- 显示界面<br>2000年09月04<br>现在的www聊天室基本全部采用框架方式,可以用 frame也可以用iframe看个人喜欢了,我的采用frame的传统方式<br><br>print("<frameset rows="*,110,0,0,0" border="0"> ");<br>print("<frameset cols="660,118" rows="*"> ");<br><br>//主显示屏幕,负责显示聊天内容<br>print("<frame name="u" src="about:blank" frameborder="NO" noresize> ");<br><br>//在线人数屏幕<br>print("<frame name="r" src="about:blank" frameborder="NO">");<br>print("</frameset> ");<br><br>//发送信息的屏幕,信息指挥中心,所有指令都要由这里发出<br>print("<frame name="d" src="send.php?name=%24name&&pass=%24pass" scrolling="no" frameborder="NO" noresize> ");<br><br>//被动更新屏幕,处理发送的信息<br>print("<frame src="about:blank" name="bl"> ");<br><br>/主动更新屏幕,显示自己和其他聊友的聊天信息<br>print("<frame src="about:blank" name="flush"> ");<br><br>//检测是否在线的屏幕,对于异常 离开,如死机,掉线等的处理<br>print("<frame src="about:blank" name="check"> ");<br>print("</frameset> ");<br><br>因为各个页面之间的程序有 联系,所以显示顺序很重要,可以看到,我这里只有发送页面不是about:blank,其他页面的显示都要先通过发送页 面的调用才能开始.<br><br><br>聊天室编程思想--大厅 -- 在线人数<br><br>大厅 -- 在线人数<br><br>我根据网易聊天室的在线人数的方法,显示当前的在 线人数,代码解释如下:<br><br>1 登陆时建立在线人名单的数组,放在body后面<br><br><br>//锁定在线 人数文件<br>while(file_exists($useronlinelock)){$pppp++;}<br>fclose(fopen($useronlinelock,"w"));<br><br>//读入在线人名单<br>$useronline = file($useronline);<br>unlink($useronlinelock);<br><br>//建立数组 list<br>print("document.writeln("list=new Array(");<br>$k=count($useronline);<br>if($k>1)<br>{<br>for($i=0;$i{<br>$usercurrent = split($split,$useronline[$i],99);<br>// 姓名+,<br>print("'$usercurrent[0]',");<br>}<br>$i=$k-1;<br>// 处理最后一个姓名 <br>$usercurrent = split($split,$useronline[$i],99);<br>print("'$usercurrent[0]'");<br>}<br>// 数组结束<br>print(")"); ");<br>?><br><br>2显示在 线人数的js<br>document.writeln('[在线人数<font color="red">'+count+'</font>]<br>');<br>document.writeln("[所有人]<br>");<br>document.writeln("<font class="p9">");<br>var j,name,club;<br>for(var i=0;i <list.length>{<br>if(list[i]!=null){<br><br>//显示每个在线人的名字 <br>document.writeln(""+list[i]+"<br>");<br>}<br>}<br>this.r.document.writeln('</list.length></font><hr>');<br><br><br>3改变聊天对象<br>function cs(name)<br>{<br>if(this.d.document==null)return;<br>if(name=='所有人')<br>{<br>this.d.add('所有人');<br>this.d.document.inputform.talkto.value='所有人 ';<br><br>//改变焦点<br>this.d.document.inputform.msg.focus();<br>return;<br>}<br>for(var i=0;i <list.length>{<br>if(list[i]==name)<br>{<br><br>//更改发送的谈话对象<br>this.d.document.inputform.talkto.value=list[i];<br>this.d.document.inputform.msg.focus();<br>return;<br>}<br>}<br><br>//错误<br>alert('此用户已离线或已改了昵称。');<br>}<br><br>4删除一个用户 <br>function del(str)<br>{<br>for(var i=0;i <list.length>if(list[i]==str)<br>{<br>delete list[i];<br>count--;<br>}<br>}<br><br><br>5增加一个用户 <br>function add(str1,str2)<br>{<br>var l=list.length;<br>for(var i=0;i <list.length><br>//如果已经在数组里面则返回<br>if(list[i]==str1)<br>return;<br><br>//增加一个用户<br>list[l]=str1;<br>count++;<br>}<br><br>6更新聊天人数的方法,定时器的使用<br>var timerID=null;<br>var timerRunning=false;<br><br>function stop()<br>{<br>//停止<br>if(timerRunning)clearTimeout(timerID);<br>timerRunning=false;<br>}<br>function start()<br>{<br>stop();<br>//调用更新在线人数的程序<br>write1();<br>}<br><br>function write1()<br>{<br>... ... ... ...<br>//设定更新时间,<br>timerID=setTimeout("start()",30000);<br>timerRunning=true;<br>}<br><br><br>这种方法比较简单的实现了在线人数的显示,当然也可以使用读入在线 人文件的方法显示在线人数,不过在改变聊天对象是会比较麻烦.<br><br><br>聊天室编程思想--指挥中心 -- 发送信息<br><br>指挥中心 -- 发送信息<br>这里是聊天室的指挥中心,所有的指令都要在这里发出<br><br>1下面是基本的发送表单代码<br><br> <form name="inputform" action="messagesend.php" target="bl" onsubmit="return(checksay());" method="POST"> <br><br><br>//下面的2个参数用于验证信息的正确性<br>print("<input type="hidden" name="name" value="$name"> ");<br>print("<input type="hidden" name="pass" value="$pass"> ");<br>?> <br><br>//聊天对象,注意加上 readonly 属性<br><input type="text" name="talkto" size="10" maxlength="20" readonly value="所有人"><br><br>//上次聊天的发送内容<br><input type="hidden" name="message" value=""><br><br>//发送的表单文本框<br><input type="text" name="msg" maxlength="120" size="34"><br><br><input type="submit" name="Submit" value="发送"><br><br> </form> <br><br>2 检查发送内容的js<br><br>var dx ='';<br>function checksay( )<br>{<br><br>//不允许发送空的发言<br>if(document.inputform.msg.value=='')<br>{<br>document.inputform.msg.focus();<br>return false;<br>}<br><br>//不允许重复发言,内容相同,对象相同<br>if ((document.inputform.msg.value==document.inputform.message.value)&&(document.inputform.talkto.value==dx))<br>{<br>alert('发言不能重复');<br>document.inputform.msg.focus();<br>return false;<br>}<br><br>//两次发言内容的间隔不能小于1秒,或者发言字数大于间隔*3<br>t2=(new Date()).getTime()/1000;<br>if(((t2-t1){<br>document.inputform.msg.focus();<br>return false;<br>}<br><br>//更新时间<br>t1=t2;<br><br>document.inputform.showsign.value=1;<br><br>//保存上次发言内容<br>document.inputform.message.value =document.inputform.msg.value;<br><br>//清空发言内容<br>document.inputform.msg.value ='';<br><br>//保存发言对象<br>dx=document.inputform.talkto.value;<br><br>//定位焦点<br>document.inputform.msg.focus();<br><br>//返回<br>return(true);<br>}<br><br>3调用信息发送程序,发布聊天者已经进入的信息<br> ><br>parent.bl.document.open();<br>parent.bl.document.write(" <meta http-equiv="refresh" content="0;url=messagesend.php?name=<? print($name); ?>&&action=enter&&pass=<? print($pass); ?>">")<br>parent.bl.document.close();<br> <br><br>发言由messagesend.php处理完成,注意输出对象为bl,也就是处理发言的框架名称,这样保证发言框架的页面内容的完整<br><br><br>聊天室编程思想--主动更新与被动更新<br><br><br>主动更新与被动更新<br><br>聊天的内容如何显示在屏幕上,一种是每隔一段时间刷新一次页面,读入全部聊天内容,然后显示,这里采用的是js的document.write的方法实现不刷新的聊天页面!<br><br>1 主页面的生成,规定了CSS类型,显示欢迎词<br>function write2(){<br>if(this.u.document==null)return;<br>this.u.document.writeln("");<br>this.u.document.writeln("");<br>this.u.document.writeln(" <style type="text/css"> ");<BR>this.u.document.writeln(".p9 { font-size: 11pt; line-height: 15pt}");<BR>this.u.document.writeln("body { font-size: 11pt; line-height: 15pt}");<BR>this.u.document.writeln("a:visited { font-size: 11pt;color: #0000FF; text-decoration: none;}");<BR>this.u.document.writeln("a:link { font-size: 11pt;color: #0000FF; text-decoration: none}");<BR>this.u.document.writeln("a:hover { font-size: 11pt;color: #FF0000}");<BR>this.u.document.writeln("</style>");<br><br>this.u.document.writeln("");<br>this.u.document.writeln("//.................. 这里插入生成在线人数组的程序段<br><br><br>this.u.document.writeln(" type="text/javascript">");<br>this.u.document.writeln(" <p class="p9" align="left">");<br>this.u.document.writeln(" </p> <p align="center">欢迎光临PlayBoy聊天室,本聊天室正在测试阶段,如有问题请与我们联系</p> ");<br>}<br><br>2 初始化进入信息,第一次进入聊天室<br><br>if($action == "enter")<br>{<br><br>/////////////////// 调用显示主屏幕的js程序 ////////////////////<br>print("parent.write2(); ");<br><br>//发言内容,某某进入聊天室了<br>$message = "$name来到聊天室".$message." ".date("m月d日 H:i")." >parent.add('$name','$photo');parent.write1(); <br>";<br>}<br>//更新发言内容<br>while(file_exists($lockfile)){ $pppp++; }<br><br>//发言的锁定<br>fclose(fopen($lockfile,"w"));<br><br>//读入发言的总句数,也就是所有人一共发了多少言!我们可以保存每一个发言,但是这样会占用大量的磁盘空间,我们采用了一种取模的方法,循环使用文件来减少文件操作!<br>$talkmessage = file($filename);<br>$number = chop($talkmessage[0]);<br><br>//发言数增加一,然后保存<br>$talkhandle = fopen($filename,"w");<br>$number++;<br>fputs($talkhandle,$number);<br>fclose($talkhandle);<br><br>/去掉锁定<br>unlink($lockfile);<br><br>//对发言总数对10取模,作为文件名保存发言内容,也就是说第11句和第1句使用同一个文件名,由于不可能同时有10句话没有更新,所以这是数在人不是非常多的情况下很好!当然,考虑到人多的情况,可以设成100.<br>$filehandle = fopen("messageonline".($number%10).".php","w");<br>fputs($filehandle,$message);<br>fclose($filehandle);<br><br>//显示进入信息<br>print("parent.u.document.writeln("$message"); ");<br><br>//调用主动刷新js程序,传递已经显示的发言数目<br>print("parent.flushwin($number) ");<br><br>//保存最后一次显示的发言<br>$last = $number;<br>}<br><br><br>3 处理发送表单的请求<br><br>//不处理空的发言和超过一定数目的发言<br>if( ($message != "")&&(strlen($message){<br><br>//检查发言者是否在线,防止意外<br>$onlineperson = file("useronline.dbf");<br>$personsign=0;<br>for($i=0;$i{<br>$person = split($split,$onlineperson[$i],99);<br>if($person[0] == $name)<br>{<br>$personsign = 1;<br>$person[3] = date("U");<br>break;<br>}<br>}<br><br>//在线时的处理程序<br>if($personsign == 1)<br>{<br><br>//添加发言时间的部分<br>$message = $message." <font size="1">".date("m月d日 H:i")."</font><br>";<br><br>//锁定发言总数文件<br>while(file_exists($lockfile)){ $pppp++; }<br>fclose(fopen($lockfile,"w"));<br><br>//读入发言总数<br>$talkmessage = file($filename);<br>$number = chop($talkmessage[0]);<br><br>//总数加1,然后保存<br>$talkhandle = fopen($filename,"w");<br>$number++;<br>fputs($talkhandle,$number);<br>fclose($talkhandle);<br>unlink($lockfile);<br><br>//总数对10取模后以文件形式保存发言内容<br>$filehandle = fopen("messageonline".($number%10).".php","w");<br>fputs($filehandle,$message);<br>fclose($filehandle);<br>}<br>}<br><br>//////////////////////////////////////////////////////////////////<br>这样,表单的处理已经完成,下面的主动更新程序将会把新的发言内容显示在屏幕上<br>//////////////////////////////////////////////////////////////////<br><br>4 主动更新的自动循环调用方法<br><br>可以使用 <meta http-equiv="reflesh" content="3;url=messageflush.php?name=<?print($name)?>&&pass=<?print($pass)&&last=<?print($last)?>的方式更新!<BR><BR>我的程序以前就是使用这种方法自动更新的,但是我发现一个问题,那就是当这个更新程序出现运行错误时,他不会产生调用下次更新的代码,造成后台更新程序停止工作!所以我采用了js定时的方法来完成同样的功能!<BR><BR>var flushtimeID=null;<BR>var flushRunning=false;<BR><BR>//上次更新标志<BR>var flushflag = true;<BR><BR>function flushstop()<BR>{<BR>if(flushtimerRunning)clearTimeout(flushtimerID);<BR>flushtimerRunning=false;<BR>}<BR>function flushstart()<BR>{<BR>flushstop();<BR><BR>//使用发送表单里面的上次显示的值<BR>flushwin(this.d.document.inputform.last.value);<BR>}<BR><BR>function flushwin(winnumber)<BR>{<BR>//如果上次更新正确,则调用下次更新<BR>if(flushflag == true)<BR>{<BR>url=">&&pass=<!--rint($pass);-->&&last="+winnumber;<br>flush.location=url<br>flushflag=false<br>}<br><br>//否则等待一个循环<br>flushtimerID=setTimeout("flushstart()",2000);<br>flushtimerRunning=true;<br>}<br><br>这种方法保证了在主程序不死的情况下,后台更新程序会一直运行下去!<br><br><br>5 主动更新程序<br> language="JavaScript" type="text/javascript"><br> <br>//读入最大的发言数目<br>$message = file($filename);<br>$number = chop($message[0]);<br><br>//从上次显示的下一个发言开始到最大发言结束,显示发言内容<br>for($i=$last+1;$i{<br>//读入下一个发言内容<br>$filename = "messageonline".($i%10).".php";<br>$message = file($filename);<br>$tempmessage = split($split,$message[0],99);<br><br>//显示发言内容<br>print("parent.u.document.writeln("$message[0]"); ");<br>}<br><br>//更新发送表单最后一个发言的数目<br>print("parent.d.document.inputform.last.value=$number; ");<br><br>//通知主程序本次更新已经完成<br>print("parent.flushflag=true; ");<br>?><br> <br><br><br>这样,每个发送的发言,经过被动更新程序处理保存到文件内,然后由一个循环的主动更新程序完成显示任务!!! <br> </list.length></list.length></list.length></count></count> </form> </font> </p>