原文作者:Akash Mehta
原文地址:http://www.sitepoint.com/article/ajax-jquery
翻译:令狐葱
Easy Ajax with jQuery中文版[1]
示例二: 使用jQuery建造聊天程序
为了展示jQuery的强大,我们将建立一个具有ajax功能的聊天程序.它允许用户发布信息,并且可以实时的更新信息--但是没有任何的页面刷新.鉴于我们将要处理一个相对比较复杂的应用,我将更加深入的讲解jQuery的特性,向您展示她那些用起来很顺手的函数.
首先,我们来规划一下这个应用.我们不需要太多东西--一个前端,一个后端,一个jQuery的库就够了.但是,将会有一些代码处理前端和后端的结合,所以我们首先应该知道预期从系统里看到什么.
规划服务器端
此应用的后端需要处理信息的提交以及输出.把这个铭记在心,这样我们就可以为后端代码构建一个草图:
- 链接数据库
- 如果有信息提交
-
- 从数据库获取信息并以XML显示
正如你所看到的,它很简单并且直白.如果你需要使用另外的语言来实现后端程序,你就可以使用这个规划来指导你.
规划
客户端
前端需要使用ajax处理反馈,就像我们在第一个例子中做的那样.它需要处理信息的提交,并且用最新的消息不间断的更新聊天窗体.然而,我们将要用到另一个特性--我们将使用
the current UNIX timestamp来展示那个消息被加载了,并且只是抓取这个信息,由此减少贷款使用以及服务器负载.下面就是客户端规划的草图:
- 页面加载的时候
- 设置当前的timestamp为0 (所有的信息都在此之后提交, 比如,所有的信息都会被获取)
- 调用函数获取消息
- function(函数): 获取新消息
- 使用POST向服务其发送请求
- 调用函数处理XML响应
- 增加一个定时器并且每秒钟调用一次此函数(服务器的性能好的话可以提高此频率)
- function: 转换新消息的XML
- 根据XML中的内容设定当前的timestamp
- 如果状态是 '2',则表示没有新消息,终止函数调用
- 否则,对反馈回来的每个消息进行处理, 以下面的格式加到聊天窗口的最上端:
-
- 提交信息的时候:
- 使用 POST向服务器发送请求, 需要指定:
- 作者姓名(用户指定)
- 消息体(用户指定)
- 标识这是一个post请求
- 最后一次向服务器请求的timestamp
- 保持输入文本框为空,便于用户在此输入信息
- 调用处理XML响应的函数 (以便让信息实时呈现出来)
看上去比服务器端有点复杂了,但是庆幸有了jQuery,代码不会很长.
规划数据库
我们将使用MySql数据库来存储信息(虽然任何sql数据库都能胜任此工作,并且代码相差也不是很大). 我们需要一个表,有四个列:消息id, 消息作者名,消息体,以及一个数字时间戳(timestamp). 下面使我们创建这个表的sql代码:
CREATE TABLE `messages` (
`id` int(7) NOT NULL auto_increment,
`user` varchar(255) NOT NULL,
`msg` text NOT NULL,
`time` int(9) NOT NULL,
PRIMARY KEY (`id`)
);
由于我们不能判断到底消息有多长,我们现在就只使用一个text字段.
服务器端代码(XML)
要建立后端,我们首先应该知道我们需要后端输出什么(来决定前端和后端的接口),由此向后工作, 下面是一个简单的XML结构:
<?xml version="1.0"?>
<response>
<status>1</status>
<time>1170323512</time>
<message>
<author>John Citizen</author>
<text>Hello world!</text>
</message>
<message>
<author>John Citizen</author>
<text>Hello world again!</text>
</message>
</response>
注意我们已经增加一个标签'status', 它的值为1. 就如我上面提到的,一个状态值为1则标示新信息请求成功,2则表示请求成功但是没有新信息. 每个消息的实例都包括作者以及其信息.
服务器端代码(php)
现在,回到服务器端.我们将使用php来实现,不过由于输出的是xml,所以你可以使用你喜欢的任何语言来写后段代码,比如Perl或者asp. 我们先定义一些配置信息这样便于我们以后对其进行修改. 我们需要数据库连接的具体信息, 我们要存储的消息的数目(数据库可以处理成千上万行数据,所以这个可以适当的设大点),以及用户进到聊天室的时候消息显示的数目. 代码如下:
$dbhost = "localhot";
$dbuser = "root";
$dbpass = "";
$dbname = "chat";
$store_num = 10;
$display_num = 10;
现在言归正传,我们继续看后端本身.数据库连接自然是必须的, 但是我们同时需要确认不让IE缓存请求数据,并且需要确认输出格式为XML. 为了能够监视所有的错误,我们设置错误汇报为"所有错误"("all errors"). 为容易操作请求数据,我们为请求中的每个参数设置一个变量,每个变量将把请求中的参数值作为其自己的值. 代码如下:
error_reporting(E_ALL);
header("Content-type: text/xml");
header("Cache-Control: no-cache");
$dbconn = mysql_connect($dbhost,$dbuser,$dbpass);
mysql_select_db($dbname,$dbconn);
foreach($_POST as $key => $value)
$$key = mysql_real_escape_string($value, $dbconn);
foreach语句遍历所有的POST数据,并且为每个参数创建一个变量,并且给它赋值(比如
path/to/file.php?variable=value将给
$variable
赋值为
"value"
).这样就简化了处理请求数据的过程,无需我们手动设定.
下面,我们将进入主要函数部分.现在我们处理消息向数据库的写入,以及根据设定的显示数目
$display_num来从数据库中获取相应数目的消息.
当我们规划客户端的时候
我提到过当提交消息的时候我们需要设定一个响应状态. 我们现在需要检查这个响应--我们给蚕食'action'赋值'postmsg',表示我们正在处理这个检查并且插入新数据到数据库.处理的时候我们需要插入新的unix时间戳(
timestamp
).
然而,我们仍然需要清理我们的数据库.根据你的数据库的限制,你可以设定存储数据的数量.一般而言,不赞成使用消息日志,所以我这里设定默认存储10条消 息.我们将使用一个函数来获取最新消息的id,并且决定是否删除.举例来说,如果我们增加第11个消息,我们使用11减去存储量(10)就得到一个id阈 值(现在是1),这样的话我们就可以删除小于等于这个阈值的所有消息,这个例子终究是删除第一条消息.有了sql,我们可以只写一条语句就处理这些.
下面的代码片段检查
'postmsg'响应,向数据库添加数据,以及清理数据库.
if(@$action == "postmsg")
{
mysql_query("INSERT INTO messages (`user`,`msg`,`time`)
VALUES ('$name','$message',".time().")");
mysql_query("DELETE FROM messages WHERE id <= ".
(mysql_insert_id($dbconn)-$store_num),$dbconn);
}
使用其他服务器端技术的开发者可以写出等价的代码.注意我们使用time函数来获取unix时间戳.我们可以假设在sql执行过程中这个时间不会改变(即 便是很慢的服务器,这段代码也可以每秒钟执行几百次). 所以当我们向客户端返回一个时间戳的时候,我们可以简单的再次调用time函数,这个值也是可信的.
剩下的工作就是要处理从数据库获取最新的消息并且以XML的形式输出.这里就要用到我上面写的那段xml代码了.然而,大部分代码是sql,我们使用sql的强大来处理这个工作,代码的执行时间不受影响. 下面是sql查询的要求:
- 它只是获取作者以及信息
- 它只是获取还没有被下载的信息--客户端有一个最后请求的时间戳,因此这个时间戳可以被插入到sql中
- 需要对消息进行排序一遍让最新的消息排在最后,并且允许逆序显示.
- 根据配置信息限制获取的消息数量.
任何熟悉sql的人都不会反对这很简单.剩下的就是这些代码了.先看看查询语句:
$messages = mysql_query("SELECT user,msg
FROM messages
WHERE time>$time
ORDER BY id ASC
LIMIT $display_num",$dbconn);
剩下的代码就相当基础,如果没有结果,就设置状态代码为0,否则,设置为1,输出最初的xml,每个消息的xml以及最终的xml.就是这些了,代码如下:
if(mysql_num_rows($messages) == 0) $status_code = 2;
else $status_code = 1;
echo "<?xml version=/"1.0/"?>/n";
echo "<response>/n";
echo "/t<status>$status_code</status>/n";
echo "/t<time>".time()."</time>/n";
while($message = mysql_fetch_array($messages))
{
echo "/t<message>/n";
echo "/t/t<author>$message[user]</author>/n";
echo "/t/t<text>$message[msg]</text>/n";
echo "/t</message>/n";
}
echo "</response>";
最终的代码在压缩包里,所以不需要复制上面的代码.现在后端程序完成了,下面我们就该更有趣的工作了--使用html和jQuery!
客户端代码(html)
在使用jQuery之前,我们先处理一下html的页面.这样的话,当我们必须确定使用那些元素来获取或者更新使用jQuery返回的数据时,我们就知道 怎么做了.我们不需要很多东西:一个外围div,一个消息段落以及一个有用户名和消息文本框的form,还有一个submit按钮.最后还需要加一个加载 信息时的提示--我们可以使用jQuery轻松的移除它.下面就是代码:
<div id="wrapper">
<p id="messagewindow"><span id="loading">Loading...</span></p>
<form id="chatform">
Name: <input type="text" id="author" />
Message: <input type="text" id="msg" />
<input type="submit" value="ok" /><br />
</form>
</div>