将程序输出为其他的语言是程序员喜爱的事情之一,在WEB上我们有 两个不同编程环境:客户端(浏览器)和服务器端,根据HTTP协议的定义, 我们可以在编写在客户端输出其他语言的服务端程序,我们选择了作为服 务端语言、javascript作为客户端输出。在本问中我们将向您演示这样用 该方案把数据存储在客户端,并且在诸如:聊天室、新闻系统或其他您想 实现的应用上达到服务端和客户端(浏览器)的最小的数据传输。
要求以下支持: PHP4 JavaScript Frames
主要思想: 我们一直试图用PHP开发一个基于HTTP协议的聊天室(HTTP CHAT ROOM), 尽管对聊天来说HTTP协议并不是个好协议,但是它可以不受防火墙或代理影响, PHP完全可以实现该功能而不必使用JAVA APPLETS,对于聊天室主要有两个问题: 第一、由于IE 不支持SERVER PUSH 技术,所以我们只有用CLIENT PULL技术(既 客户端自动刷新),第二个问题就更深一层了:因为该思想是在客户端刷新,所以服 务端每次必须传送所有的消息,这意味着大量的数据传输,这也正是聊天室延迟的主 要原因,本文试图解决该问题: 使用框架技术(frames) 你能够刷新指定页面,而不必重新装载别的页面,这可 以减少服务/客户端(C/S)数据传输量。我们的模型就是基于该方案。 "master"文件:定义框架结构 "loader"页面:导入数据 "display"页面:显示数据 在该方案,"loder"框每"x"秒自动刷新一次??我们的思想是把数据存储在"master" 文件内,这样"loder"页面只要向服务端请求客户端所没有的数据就可以了我们使用时间戳标(timestamp) 记每个消息来决定那些消息必须传给客户端那些不必传输。我们使用PHP4。0的会话管理(session) 存储客户端的最后更新的时间戳(last timestamp)以使时间戳对服务端和客户端均可见。当"loader"文件 从"master"文件收到数据(注意:"master"文件很大,但是它只传送一次)时,就刷新显示页("diaplay") 而"display"页只是简单的调用"master"文件的名为"displaymsgs()"的javascript 函数显示消息。该函数动态显示 存储在"master"文件的数据,以下是大体流程图: 1。浏览器请求"master"页(框架),"master"页从服务器端传送到客户端(浏览器),然后"master" 文件生成框架,并且将"loader"和"display"页调到客户端。 2。在服务端,"loader" 文件将分析:如果客户端没定义"timestamp" session 变量,"loder"文件将 从服务端得到所有数据,并生成javascript代码将数据存入"master"文件,然后将"timestamp"变量存为 session 变量。 3。"loder"页面生成javascript 代码刷新 "display"页面。 4。刷新请求使得"display"页面调用"diaplaymsgs()"javascript 函数显示数据 5。每隔"x" 秒回到步骤2
我们可以该思想如下: ======================================================== "master"文件:非常大,定义了displaymsgs() 函数和存储数据和初始值。 "loader"文件:小,从服务端取回数据,生成javascript 代码 "display"文件:非常小,调用"master"文件的"diaplaymsgs()"函数 ========================================================= 注:“master"文件只传送一次 "loder" 和 "display" 文件每隔"x"秒刷新一次 第一次传送的时候"loder"可能会很大,但以后就会很小 "diaplay"文件一直不变
如果您对以上的思路还是不太清楚的话,以下我们将建立一个聊天室具体讲解该方法,这个聊天室只是为了简单的演示 所以可能并不是很有用,但是您完全可以使用该思想建立更复杂的聊天室,记住这个思想并不是只用与聊天室 。:)
首先请您使用mysql数据库表单: ============================ 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"文件是发言框,提供用户输入发言框。
"display"文件内容: ===================== <script> top.displaymsgs(); </script> ==================== "display"文件是不是很小? :) "loader"文件: ==================== <?php
session_start(); // 在这使用 Sessions !
if(!isset($timestamp)) { //如果"timestamp"没有定义,则定义并设为0 $timestamp=0; }
$dab=mysql_connect("localhost","user","password"); // 打开数据库 mysql_select_db("testbase",$dab);
// 查找客户端所没有的信息 $query="select * from testeable where timestamp>'$timestamp'"; $result=mysql_query($query,$dab); $msgs=array();
// 在这个循环,我们存储最新消息/数据,并设置"timestamp"为当前最大值 while($res=mysql_fetch_array($result)) { $msgs[]=$res["message"]; if($res["timestamp"]>$timestamp) { $timestamp=$res["timestamp"]; } } session_register("timestamp"); // 注册"timestamp"变量
echo '<script>';
// 在这个循环我们生成javascript代码 // 把最新从服务端得到的数据存储到"master"页面里(注意:使用"top"指向最顶窗口(master) for($i=0;$i<$count($msgs);$i++) { ?> top.lines[top.lines.length]="<?php print("$msgs[$i]"); ?>"; <?php }
//现在我们将生成"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; }
// 显示表单,产生"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"页提交发言时,马上刷新"display"页面,这可以达到对发言人来说马上发言马上 显示,更体现实时性。 正如您所看到的,这个聊天室很简单,这就是最小化客户/服务(C/S)数据传输技能,使用这个技术您可以达到最 小的数据传输,再次提醒您:该技术并不是这用于聊天室! ======================================================= 以上在win98+apache1.3+php4.03平台测试通过!
|