將程序輸出為其他的語言是程序員喜愛的事情之一,在WEB上我們有 兩個不同編程環(huán)境:客戶端(瀏覽器)和服務(wù)器端,根據(jù)HTTP協(xié)議的定義, 我們可以在編寫在客戶端輸出其他語言的服務(wù)端程序,我們選擇了作為服 務(wù)端語言、javascript作為客戶端輸出。在本問中我們將向您演示這樣用 該方案把數(shù)據(jù)存儲在客戶端,并且在諸如:聊天室、新聞系統(tǒng)或其他您想 實現(xiàn)的應(yīng)用上達到服務(wù)端和客戶端(瀏覽器)的最小的數(shù)據(jù)傳輸。
要求以下支持: PHP4 JavaScript Frames
主要思想: 我們一直試圖用PHP開發(fā)一個基于HTTP協(xié)議的聊天室(HTTP CHAT ROOM), 盡管對聊天來說HTTP協(xié)議并不是個好協(xié)議,但是它可以不受防火墻或代理影響, PHP完全可以實現(xiàn)該功能而不必使用JAVA APPLETS,對于聊天室主要有兩個問題: 第一、由于IE 不支持SERVER PUSH 技術(shù),所以我們只有用CLIENT PULL技術(shù)(既 客戶端自動刷新),第二個問題就更深一層了:因為該思想是在客戶端刷新,所以服 務(wù)端每次必須傳送所有的消息,這意味著大量的數(shù)據(jù)傳輸,這也正是聊天室延遲的主 要原因,本文試圖解決該問題: 使用框架技術(shù)(frames) 你能夠刷新指定頁面,而不必重新裝載別的頁面,這可 以減少服務(wù)/客戶端(C/S)數(shù)據(jù)傳輸量。我們的模型就是基于該方案。 "master"文件:定義框架結(jié)構(gòu) "loader"頁面:導(dǎo)入數(shù)據(jù) "display"頁面:顯示數(shù)據(jù) 在該方案,"loder"框每"x"秒自動刷新一次——我們的思想是把數(shù)據(jù)存儲在"master" 文件內(nèi),這樣"loder"頁面只要向服務(wù)端請求客戶端所沒有的數(shù)據(jù)就可以了我們使用時間戳標(biāo)(timestamp) 記每個消息來決定那些消息必須傳給客戶端那些不必傳輸。我們使用PHP4。0的會話管理(session) 存儲客戶端的最后更新的時間戳(last timestamp)以使時間戳對服務(wù)端和客戶端均可見。當(dāng)"loader"文件 從"master"文件收到數(shù)據(jù)(注意:"master"文件很大,但是它只傳送一次)時,就刷新顯示頁("diaplay") 而"display"頁只是簡單的調(diào)用"master"文件的名為"displaymsgs()"的javascript 函數(shù)顯示消息。該函數(shù)動態(tài)顯示 存儲在"master"文件的數(shù)據(jù),以下是大體流程圖: 1。瀏覽器請求"master"頁(框架),"master"頁從服務(wù)器端傳送到客戶端(瀏覽器),然后"master" 文件生成框架,并且將"loader"和"display"頁調(diào)到客戶端。 2。在服務(wù)端,"loader" 文件將分析:如果客戶端沒定義"timestamp" session 變量,"loder"文件將 從服務(wù)端得到所有數(shù)據(jù),并生成javascript代碼將數(shù)據(jù)存入"master"文件,然后將"timestamp"變量存為 session 變量。 3。"loder"頁面生成javascript 代碼刷新 "display"頁面。 4。刷新請求使得"display"頁面調(diào)用"diaplaymsgs()"javascript 函數(shù)顯示數(shù)據(jù) 5。每隔"x" 秒回到步驟2
我們可以該思想如下: ======================================================== "master"文件:非常大,定義了displaymsgs() 函數(shù)和存儲數(shù)據(jù)和初始值。 "loader"文件:小,從服務(wù)端取回數(shù)據(jù),生成javascript 代碼 "display"文件:非常小,調(diào)用"master"文件的"diaplaymsgs()"函數(shù) ========================================================= 注:“master"文件只傳送一次 "loder" 和 "display" 文件每隔"x"秒刷新一次 第一次傳送的時候"loder"可能會很大,但以后就會很小 "diaplay"文件一直不變
如果您對以上的思路還是不太清楚的話,以下我們將建立一個聊天室具體講解該方法,這個聊天室只是為了簡單的演示 所以可能并不是很有用,但是您完全可以使用該思想建立更復(fù)雜的聊天室,記住這個思想并不是只用與聊天室 。:)
首先請您使用mysql數(shù)據(jù)庫表單: ============================ create table testeable ( timestamp datetime, message text ); ============================ "master"文件如下: ================================================ <script> lines=new Array(); function displaymsgs() { for(i=0;i<lines.length;i++) { display.document.write(lines[i]); display.document.write('<BR>'); } } </script> <frameset cols="1" rows="20,60,20" border="0"> <frame name="loader" src="loader.php"> <frame name="display" src="display.php"> <frame name="form" src="form.php"> </frameset> ================================================== 注:"form"文件是發(fā)言框,提供用戶輸入發(fā)言框。
"display"文件內(nèi)容: ===================== <script> top.displaymsgs(); </script> ==================== "display"文件是不是很? :) "loader"文件: ==================== <?php
session_start(); // 在這使用 Sessions !
if(!isset($timestamp)) { //如果"timestamp"沒有定義,則定義并設(shè)為0 $timestamp=0; }
$dab=mysql_connect("localhost","user","password"); // 打開數(shù)據(jù)庫 mysql_select_db("testbase",$dab);
// 查找客戶端所沒有的信息 $query="select * from testeable where timestamp>'$timestamp'"; $result=mysql_query($query,$dab); $msgs=array();
// 在這個循環(huán),我們存儲最新消息/數(shù)據(jù),并設(shè)置"timestamp"為當(dāng)前最大值 while($res=mysql_fetch_array($result)) { $msgs[]=$res["message"]; if($res["timestamp"]>$timestamp) { $timestamp=$res["timestamp"]; } } session_register("timestamp"); // 注冊"timestamp"變量
echo '<script>';
// 在這個循環(huán)我們生成javascript代碼 // 把最新從服務(wù)端得到的數(shù)據(jù)存儲到"master"頁面里(注意:使用"top"指向最頂窗口(master) for($i=0;$i<$count($msgs);$i++) { ?> top.lines[top.lines.length]="<?php print("$msgs[$i]"); ?>"; <?php }
//現(xiàn)在我們將生成"javascript"代碼 ,使 "display"頁刷新
?> top.display.location.reload(); </script>
<!-- 注意是用 javascript 的"setInterval()" 方法使得"loader"頁面每隔4秒刷新一次 --> <body onLoad="window.setInterval('location.reload()',4000);"> </body> ======================================= "form"頁面: ==================== <?php
session_start();
if (!isset($timestamp)) { $timestamp=0; }
// 顯示表單,產(chǎn)生"timestamp"變量. if (isset($msg)) { $dab=mysql_connect("localhost","root","seldon"); mysql_select_db("testbase",$dab); $query="insert into testeable(timestamp,message) values(now(),'$msg')"; mysql_query($query,$dab); // 得到timestamp 后的所有消息 $query="select * from testeable where timestamp>'$tt'"; $result=mysql_query($query,$dab); $msgs=array();$i=0;$timestamp=0; while($res=mysql_fetch_array($result)) { $msgs[]=$res["message"]; if($res["timestamp"]>$timestamp) { $tt=$res["timestamp"]; } } session_register("timestamp"); ?> <script> <?php for($i=0;$i<$count($msgs);$i++) { ?> top.lines[top.lines.length]="<?print("$msgs[$i]");?>"; <?php } ?> top.display.location.reload(); //刷新"display"頁 </script> <?php } ?> <form name="foo" action="<?php print("$PHP_SELF"); ?>" method="post"> Message:<input type="text" name="msg"> <input type="submit" name="newmsg" value="send"> </form> ===================================================== 注:我們使得在"form"頁提交發(fā)言時,馬上刷新"display"頁面,這可以達到對發(fā)言人來說馬上發(fā)言馬上 顯示,更體現(xiàn)實時性。 正如您所看到的,這個聊天室很簡單,這就是最小化客戶/服務(wù)(C/S)數(shù)據(jù)傳輸技能,使用這個技術(shù)您可以達到最 小的數(shù)據(jù)傳輸,再次提醒您:該技術(shù)并不是這用于聊天室! ======================================================= 以上在win98+apache1.3+php4.03平臺測試通過! 如有建議或疑問請和飛揚社區(qū)聯(lián)系(http://feiyschool.51.net) 或者發(fā)EMAIL到feiyhy@sina.com 請您多多賜教,謝謝! =============================== 英文原作者:Luis Argerich, Alejandro Mitrou 英文原文所在網(wǎng)址:http://www.phpbuilder.com
【本文版權(quán)歸作者與奧索網(wǎng)共同擁有,如需轉(zhuǎn)載,請注明作者及出處】
|