1 頁面登陸的基本要素
你可以在我的竹葉看到登陸 的表單,這里提供了最基本的登陸表單項
(1)登陸表單
<form method=POST name=chatform action=chat/login.php?action=enter onSubmit="b1_submit();return true;" target="howtodo">
(a)聊天表單的名字為chatform,我使用action=enter作為進入聊天室的入口,如果沒有這個參數,則顯示登陸頁 面.
(b)在表單提交時,先調用b1_submit()建立聊天的窗口
(c)聊天的目標窗口為b1_submit()建立 的howtodo窗口
(2)表單項
昵稱:<input type=text name=name size=15 maxlength="10">
密碼:<input type=password name=pass size=15 maxlength="10">
<input type=submit name=submit value=登陸 style="width:100">
<input type=reset name=reset value=重添 style="width:50">
(a)各表單項一定要設定最大允許長度 maxlength
(3)建立聊天窗口的js
<script LANGUAGE="javascript">
function b1_submit(){
chat=window.open('',"howtodo",'Status=no,scrollbars=no,resizable=no');
chat.moveTo(0,0);
chat.resizeTo(screen.availWidth,screen.availHeight);
chat.outerWidth=screen.availWidth;
chat.outerHeight=screen.availHeight;
}
這段代碼先 打開一個沒有狀態欄,滾動條,可調整尺寸的howtodo窗口!然后移動到屏幕左上角,然后放大到允許的屏幕大小.
聊天室編程思想--大門 -- 通行證
大門 -- 通行證
聊天室可以采用完全自由的方式運行,你可以隨意 輸入呢稱,不用密碼,不保存你的聊天狀態,優點是:自由,非常適合于游客!另外一個方法是注冊聊天室,每個進入 聊天室的人都要輸入自己的用戶名和密碼才能進入!優點:充分體現個性,非常適合于老朋友,他們的呢稱不會被 人惡意侵占使用.我的聊天室使用注冊方法!
注冊通常采用2種方法:1,先注冊然后進入聊天;2,自動注 冊,然后在里面修改自己的資料!我采用第2種方法!!每個新進入的聊友的用戶名會被自動保存到注冊到數據庫內 ,下次登陸必須輸入準確的密碼才能進入!
下面是判斷部分!本程序使用文本數據庫 !
//$useronline為在線人的數據文件名稱
//$useronlinelock為在線人的鎖定標志
//$register為已經注冊的數據文件名稱
//$registerlock為注冊文件的鎖定標志
//$split為分隔 符
//登陸參數 enter
if($action == "enter")
{
//當前時間秒數
$timecurrent = date("U");
//鎖定在線人數文件,防止同時修改同一個文件
while( file_exists($useronlinelock))
{
if(!file_exists($useronlinelock))
{
break;
}
}
//創建臨時文件
fclose(fopen($useronlinelock,"w"));
//讀入在線用戶和已經注冊用戶的信息:密碼,昵稱,更新時間
$useronline = file($useronline);
$register = file($register);
//用于判斷登 陸是否成功的標志
$namesign=0;
//判斷用戶名,密碼的錯誤,用戶名不允許為空,不允許超過10 個字符,密碼不允許超過20個字符
if(($name =="") || (strlen($name) > 10) || (strlen($pass) > 20) )
{
print("沒有昵稱或密碼過長");
//登陸失敗
$namesign=1;
//刪除臨時文件
unlink($useronlinelock);
}
else
{
//查找是否已經有人注冊或者密碼錯誤
$foundsign=0;
for($i=0;$i<count($register);$i++)
{
//分割
$tempregister = split($split,$register[$i],99);
//找到已經注冊的用戶名
if( $name == $tempregister[0] )
{
//已經找到標志
$foundsign=1;
//密碼正確嗎
if($pass != $tempregister[1])
print("密碼錯了!");
//登陸失敗
$namesign=1;
unlink($useronlinelock);
break;
}
else
{
//老用戶登陸成功
$namesign=0;
break;
}
}
}
//如果沒有找到這個用戶名,那么就自動注冊
if(!$foundsign)
{
//保存用戶名和密碼
$handle = fopen($register,"a");
fputs($handle,"$name$split$pass$split ");
fclose($handle);
//新 用戶登陸成功
$namesign=0;
}
}
}
if(!$namesign)
{
//更新在線人的名單
$useronlinehandle = fopen($useronline,"w");
//判斷是否已經在里面,只是刷新頁面
$updatesign = 0;
for($i=0;$i<count($useronline);$i++)
{
$usertemp=split($split,chop($useronline[$i]),99);
if($name == $usertemp[0])
{
//更新標志
$updatesign = 1;
fputs($useronlinehandle,$useronline[$i]);
}
else
{
fputs($useronlinehandle,$useronline[$i]);
}
}
//如 果沒有在里面,則增加到里面
if(!$updatesign)
fputs($useronlinehandle,"$name$split$level$split$pass$split$timecurrent ");
fclose($useronlinehandle);
//去掉縮定
unlink($useronlinelock);
//登陸成 功
}
到這里,用戶的驗證已經完成,聊友已經合法的進入了聊天室,攜帶者呢稱和密碼
聊天室編程思想--大廳 -- 顯示界面
大廳 -- 顯示界面
2000年09月04
現在的www聊天室基本全部采用框架方式,可以用 frame也可以用iframe看個人喜歡了,我的采用frame的傳統方式
print("<frameset rows="*,110,0,0,0" border=0> ");
print("<frameset cols="660,118" rows="*"> ");
//主顯示屏幕,負責顯示聊天內容
print("<frame name=u src=about:blank frameborder="NO" noresize> ");
//在線人數屏幕
print("<frame name=r src="about:blank" frameborder="NO">");
print("</frameset> ");
//發送信息的屏幕,信息指揮中心,所有指令都要由這里發出
print("<frame name=d src=send.php?name=$name&&pass=$pass scrolling='no' frameborder="NO" noresize> ");
//被動更新屏幕,處理發送的信息
print("<frame src="about:blank" name="bl"> ");
/主動更新屏幕,顯示自己和其他聊友的聊天信息
print("<frame src="about:blank" name="flush"> ");
//檢測是否在線的屏幕,對于異常 離開,如死機,掉線等的處理
print("<frame src="about:blank" name="check"> ");
print("</frameset> ");
因為各個頁面之間的程序有 聯系,所以顯示順序很重要,可以看到,我這里只有發送頁面不是about:blank,其他頁面的顯示都要先通過發送頁 面的調用才能開始.
聊天室編程思想--大廳 -- 在線人數
大廳 -- 在線人數
我根據網易聊天室的在線人數的方法,顯示當前的在 線人數,代碼解釋如下:
1 登陸時建立在線人名單的數組,放在body后面
<?
//鎖定在線 人數文件
while(file_exists($useronlinelock)){$pppp++;}
fclose(fopen($useronlinelock,"w"));
//讀入在線人名單
$useronline = file($useronline);
unlink($useronlinelock);
//建立數組 list
print("document.writeln("list=new Array(");
$k=count($useronline);
if($k>1)
{
for($i=0;$i<($k-1);$i++)
{
$usercurrent = split($split,$useronline[$i],99);
// 姓名+,
print("'$usercurrent[0]',");
}
$i=$k-1;
// 處理最后一個姓名
$usercurrent = split($split,$useronline[$i],99);
print("'$usercurrent[0]'");
}
// 數組結束
print(")"); ");
?>
2顯示在 線人數的js
document.writeln('[在線人數<font color=red>'+count+'</font>]<br>');
document.writeln("[<a href="javascript:parent.cs('所有人')">所有人</a>]<br>");
document.writeln("<font class='p9'>");
var j,name,club;
for(var i=0;i<list.length;i=i+1)
{
if(list[i]!=null){
//顯示每個在線人的名字
document.writeln("<a href="javascript:parent.cs('"+list[i]+"')" title='"+list[i]+"'>"+list[i]+"</a><br>");
}
}
this.r.document.writeln('</font><hr>');
3改變聊天對象
function cs(name)
{
if(this.d.document==null)return;
if(name=='所有人')
{
this.d.add('所有人');
this.d.document.inputform.talkto.value='所有人 ';
//改變焦點
this.d.document.inputform.msg.focus();
return;
}
for(var i=0;i<list.length;i=i+1)
{
if(list[i]==name)
{
//更改發送的談話對象
this.d.document.inputform.talkto.value=list[i];
this.d.document.inputform.msg.focus();
return;
}
}
//錯誤
alert('此用戶已離線或已改了昵稱。');
}
4刪除一個用戶
function del(str)
{
for(var i=0;i<list.length;i=i+1)
if(list[i]==str)
{
delete list[i];
count--;
}
}
5增加一個用戶
function add(str1,str2)
{
var l=list.length;
for(var i=0;i<list.length;i=i+1)
//如果已經在數組里面則返回
if(list[i]==str1)
return;
//增加一個用戶
list[l]=str1;
count++;
}
6更新聊天人數的方法,定時器的使用
var timerID=null;
var timerRunning=false;
function stop()
{
//停止
if(timerRunning)clearTimeout(timerID);
timerRunning=false;
}
function start()
{
stop();
//調用更新在線人數的程序
write1();
}
function write1()
{
... ... ... ...
//設定更新時間,
timerID=setTimeout("start()",30000);
timerRunning=true;
}
這種方法比較簡單的實現了在線人數的顯示,當然也可以使用讀入在線 人文件的方法顯示在線人數,不過在改變聊天對象是會比較麻煩.
聊天室編程思想--指揮中心 -- 發送信息
指揮中心 -- 發送信息
這里是聊天室的指揮中心,所有的指令都要在這里發出
1下面是基本的發送表單代碼
<form name=inputform action='messagesend.php' target='bl' onsubmit='return(checksay());' method=POST>
<?
//下面的2個參數用于驗證信息的正確性
print("<input type='hidden' name='name' value='$name'> ");
print("<input type='hidden' name='pass' value='$pass'> ");
?>
//聊天對象,注意加上 readonly 屬性
<input type="text" name="talkto" size="10" maxlength="20" readonly value="所有人">
//上次聊天的發送內容
<input type='hidden' name='message' value=''>
//發送的表單文本框
<input type="text" name="msg" maxlength="120" size="34">
<input type="submit" name="Submit" value="發送">
</form>
2 檢查發送內容的js
var dx ='';
function checksay( )
{
//不允許發送空的發言
if(document.inputform.msg.value=='')
{
document.inputform.msg.focus();
return false;
}
//不允許重復發言,內容相同,對象相同
if ((document.inputform.msg.value==document.inputform.message.value)&&(document.inputform.talkto.value==dx))
{
alert('發言不能重復');
document.inputform.msg.focus();
return false;
}
//兩次發言內容的間隔不能小于1秒,或者發言字數大于間隔*3
t2=(new Date()).getTime()/1000;
if(((t2-t1)<1)||((t2-t1)*3<document.inputform.msg.value.length))
{
document.inputform.msg.focus();
return false;
}
//更新時間
t1=t2;
document.inputform.showsign.value=1;
//保存上次發言內容
document.inputform.message.value =document.inputform.msg.value;
//清空發言內容
document.inputform.msg.value ='';
//保存發言對象
dx=document.inputform.talkto.value;
//定位焦點
document.inputform.msg.focus();
//返回
return(true);
}
3調用信息發送程序,發布聊天者已經進入的信息
<script>
parent.bl.document.open();
parent.bl.document.write("<meta http-equiv='refresh' content='0;url=messagesend.php?name=<? print($name); ?>&&action=enter&&pass=<? print($pass); ?>'>")
parent.bl.document.close();
</script>
發言由messagesend.php處理完成,注意輸出對象為bl,也就是處理發言的框架名稱,這樣保證發言框架的頁面內容的完整
聊天室編程思想--主動更新與被動更新
主動更新與被動更新
聊天的內容如何顯示在屏幕上,一種是每隔一段時間刷新一次頁面,讀入全部聊天內容,然后顯示,這里采用的是js的document.write的方法實現不刷新的聊天頁面!
1 主頁面的生成,規定了CSS類型,顯示歡迎詞
function write2(){
if(this.u.document==null)return;
this.u.document.writeln("<html><head>");
this.u.document.writeln("<meta http-equiv=Content-Type content=text/html; charset=gb2312>");
this.u.document.writeln("<style type=text/css>");
this.u.document.writeln(".p9 { font-size: 11pt; line-height: 15pt}");
this.u.document.writeln("body { font-size: 11pt; line-height: 15pt}");
this.u.document.writeln("a:visited { font-size: 11pt;color: #0000FF; text-decoration: none;}");
this.u.document.writeln("a:link { font-size: 11pt;color: #0000FF; text-decoration: none}");
this.u.document.writeln("a:hover { font-size: 11pt;color: #FF0000}");
this.u.document.writeln("</style>");
this.u.document.writeln("</head>");
this.u.document.writeln("<body);
//.................. 這里插入生成在線人數組的程序段
this.u.document.writeln("<script>");
this.u.document.writeln("<p class=p9 align=left>");
this.u.document.writeln("<p align=center>歡迎光臨PlayBoy聊天室,本聊天室正在測試階段,如有問題請與<a href=mailto:pclearcase/" target="_blank" >ccastle@sina.com>我們聯系</a></p>");
}
2 初始化進入信息,第一次進入聊天室
if($action == "enter")
{
/////////////////// 調用顯示主屏幕的js程序 ////////////////////
print("parent.write2(); ");
//發言內容,某某進入聊天室了
$message = "<a href=javascript:parent.cs('$name'); target=d>$name</a>來到聊天室".$message." ".date("m月d日 H:i")."<script>parent.add('$name','$photo');parent.write1();</script><br>";
}
//更新發言內容
while(file_exists($lockfile)){ $pppp++; }
//發言的鎖定
fclose(fopen($lockfile,"w"));
//讀入發言的總句數,也就是所有人一共發了多少言!我們可以保存每一個發言,但是這樣會占用大量的磁盤空間,我們采用了一種取模的方法,循環使用文件來減少文件操作!
$talkmessage = file($filename);
$number = chop($talkmessage[0]);
//發言數增加一,然后保存
$talkhandle = fopen($filename,"w");
$number++;
fputs($talkhandle,$number);
fclose($talkhandle);
/去掉鎖定
unlink($lockfile);
//對發言總數對10取模,作為文件名保存發言內容,也就是說第11句和第1句使用同一個文件名,由于不可能同時有10句話沒有更新,所以這是數在人不是非常多的情況下很好!當然,考慮到人多的情況,可以設成100.
$filehandle = fopen("messageonline".($number%10).".php","w");
fputs($filehandle,$message);
fclose($filehandle);
//顯示進入信息
print("parent.u.document.writeln("$message"); ");
//調用主動刷新js程序,傳遞已經顯示的發言數目
print("parent.flushwin($number) ");
//保存最后一次顯示的發言
$last = $number;
}
3 處理發送表單的請求
//不處理空的發言和超過一定數目的發言
if( ($message != "")&&(strlen($message)<150))
{
//檢查發言者是否在線,防止意外
$onlineperson = file("useronline.dbf");
$personsign=0;
for($i=0;$i<count($onlineperson);$i++)
{
$person = split($split,$onlineperson[$i],99);
if($person[0] == $name)
{
$personsign = 1;
$person[3] = date("U");
break;
}
}
//在線時的處理程序
if($personsign == 1)
{
//添加發言時間的部分
$message = $message." <font size=1>".date("m月d日 H:i")."</font><br>";
//鎖定發言總數文件
while(file_exists($lockfile)){ $pppp++; }
fclose(fopen($lockfile,"w"));
//讀入發言總數
$talkmessage = file($filename);
$number = chop($talkmessage[0]);
//總數加1,然后保存
$talkhandle = fopen($filename,"w");
$number++;
fputs($talkhandle,$number);
fclose($talkhandle);
unlink($lockfile);
//總數對10取模后以文件形式保存發言內容
$filehandle = fopen("messageonline".($number%10).".php","w");
fputs($filehandle,$message);
fclose($filehandle);
}
}
//////////////////////////////////////////////////////////////////
這樣,表單的處理已經完成,下面的主動更新程序將會把新的發言內容顯示在屏幕上
//////////////////////////////////////////////////////////////////
4 主動更新的自動循環調用方法
可以使用<meta http-equiv="reflesh" content="3;url=messageflush.php?name=<?print($name)?>&&pass=<?print($pass)&&last=<?print($last)?>的方式更新!
我的程序以前就是使用這種方法自動更新的,但是我發現一個問題,那就是當這個更新程序出現運行錯誤時,他不會產生調用下次更新的代碼,造成后臺更新程序停止工作!所以我采用了js定時的方法來完成同樣的功能!
var flushtimeID=null;
var flushRunning=false;
//上次更新標志
var flushflag = true;
function flushstop()
{
if(flushtimerRunning)clearTimeout(flushtimerID);
flushtimerRunning=false;
}
function flushstart()
{
flushstop();
//使用發送表單里面的上次顯示的值
flushwin(this.d.document.inputform.last.value);
}
function flushwin(winnumber)
{
//如果上次更新正確,則調用下次更新
if(flushflag == true)
{
url="messageflush.php?name=<? print($name); ?>&&pass=<? print($pass); ?>&&last="+winnumber;
flush.location=url
flushflag=false
}
//否則等待一個循環
flushtimerID=setTimeout("flushstart()",2000);
flushtimerRunning=true;
}
這種方法保證了在主程序不死的情況下,后臺更新程序會一直運行下去!
5 主動更新程序
<script Language='JavaScript'>
<?
//讀入最大的發言數目
$message = file($filename);
$number = chop($message[0]);
//從上次顯示的下一個發言開始到最大發言結束,顯示發言內容
for($i=$last+1;$i<=$number;$i++)
{
//讀入下一個發言內容
$filename = "messageonline".($i%10).".php";
$message = file($filename);
$tempmessage = split($split,$message[0],99);
//顯示發言內容
print("parent.u.document.writeln("$message[0]"); ");
}
//更新發送表單最后一個發言的數目
print("parent.d.document.inputform.last.value=$number; ");
//通知主程序本次更新已經完成
print("parent.flushflag=true; ");
?>
</script>
這樣,每個發送的發言,經過被動更新程序處理保存到文件內,然后由一個循環的主動更新程序完成顯示任務!!!
原文轉自:http://www.anti-gravitydesign.com