20150220 Comet反向Ajax技术-在线客服系统之服务端
2015-02-20 李海沿
前面我们讲了comet反向Ajax模型原理 以及实现了简单的实时页面聊天系统。
(地址:http://www.cnblogs.com/lihaiyan/p/4281049.html)
本文中,我们在它的基础上来实现一个在线客服系统的服务端。
一、搭建页面客服系统框架
1.首先新建一个kefu.html网页
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <title>在线客服系统之服务端</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script type="text/javascript"></script> <style type="text/css"></style> </head>
<body> <h1> Conmet反向Ajax技术-在线客服系统之服务端 </h1> <h3>原理:iframe + 长连接获取实时内容,并更新到父页面 </h3> <iframe src="commet_iframe.php"></iframe> </body>
</html> |
2.接着我们将前面我们已经实现的实时页面聊天系统的内容显示在ifram里面,则新建一个commet_iframe.php文件,内容和前面的代码一样
ob_start(); <?php ob_clean(); set_time_limit(0); //脚本运行不受限制 //连接数据库 $conn = mysql_connect('localhost','root',''); mysql_query('use test',$conn); mysql_query('set names utf8',$conn); while(1){
$sql = 'select * from msg where name ="LoverXueEr" and isread = 0'; $rs = mysql_query($sql,$conn); $msg = mysql_fetch_assoc($rs); if(!empty($msg)){ //若消息不为空 //将消息置为已读 $sql = " update msg set isread = 1 where name= '".$msg['name']."' && content= '".$msg['content']."' && num= ".$msg['num']; mysql_query($sql,$conn); echo "<b>",$msg['name'],"</b> \t",strftime("%d/%m/%Y %H:%M:%S"),"<br/>"; echo $msg['content'],'<br/>'; ob_flush(); flush(); } sleep(1); } ?> |
3.写好后,来测试一下我们初步的成功
进入我们的数据库(此处不懂的话,请参考博客http://www.cnblogs.com/lihaiyan/p/4281049.html),
接下来,我们使用MySQL命令:
insert into msg(name,isread,content) value('LoverXueEr',0,'hello');
来模拟客户端发送消息(客户端系统我们将会在下次实现),可以发现,我们客户端发送的数据,都实时并且正确的显示在了我们的iframe框架里面,很成功,有木有。
3.但这并不是我们所要实现的框架,接下来,我们在html文件中,增加一个div,我们把消息的内容在div中。
如图所示,在iframe前面,我们增加一个<div id="msgzone"></div>
并且css中设置其边框为 实线 1px 灰色,设置其宽为 300px 高为200px 滚动u
并且把iframe的属性设置为 宽为0 高为0,也就是把iframe隐藏:
接着我们想办法把前面iframe中显示的消息转移我们的div中来
所以在php中,我们就不直接echo消息了,而是echo一段JavaScript的代码:
php中将我们从数据库中的数组使用:json_encode() 自动编码,在script中json编码后的字符串会被理解为一个对象,在script中可直接使用对象名.xxxx来使用。
(json不懂的请参考博文http://www.cnblogs.com/lihaiyan/p/4274255.html),
然后将编码后的字符串发送给html中的comet函数中。
此时我们在html文件中实现comet函数,并且在将前面我们php页面传递过来的msg在console控制台打印出来,
运行一下,正如我们前面所述的,可以发现,我们控制台中得到了一个object对象,这正是我们所需要的。
接下来,我们在comet函数中将我们的数组格式化一下,并且打印在console中测试一下:
<script type="text/javascript"> function comet(msg){ //console.log(msg); var cont = ''; cont += "<b>客户端"+msg.name+"</b>\t"+msg.time+"<br/>"; cont += msg.content + "<br/>"; console.log(cont); } </script> |
如图所示:
如图所示,结果很成功:
好了,现在是时候将消息显示在我们的div中了。结果非常成功,如图所示:
附上当前commet_iframe.php代码:
1 ob_start();
2 <?php
3 ob_clean();
4 set_time_limit(0); //脚本运行不受限制
5
6 //连接数据库
7 $conn = mysql_connect('localhost','root','');
8 mysql_query('use test',$conn);
9 mysql_query('set names utf8',$conn);
10 $msg_tmp = "";
11 while(1){
12
13 $sql = 'select * from msg where name ="LoverXueEr" and isread = 0 limit 1';
14 $rs = mysql_query($sql,$conn);
15 $msg = mysql_fetch_assoc($rs);
16 if(!empty($msg)){ //若消息不为空
17 //将我们已读取的消息置为已读
18 $sql = " update msg set isread = 1 where name= '".$msg['name']."' && content= '".$msg['content']."' && num= ".$msg['num'] ;
19 mysql_query($sql,$conn);
20
21 //格式化我们的消息为一个字符串
22 //$msg_tmp = "<b>".$msg['name']."</b> \t".strftime("%d/%m/%Y %H:%M:%S")."<br/>" . $msg['content'].'<br/>';
23 //json_encode() 自动编码
24 $msg[time]=strftime("%d/%m/%Y %H:%M:%S");
25 $msg_tmp = json_encode($msg);
26 echo '<script type="text/javascript">';
27 //将消息传递给comet函数
28 echo 'parent.window.comet('.$msg_tmp.');';
29 echo '</script>';
30
31 ob_flush();
32 flush();
33 }
34 sleep(1);
35 }
36 ?>
View commet_iframe.php
附上当前kefu.html代码:
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2 <html>
3 <head>
4 <title>在线客服系统之服务端</title>
5 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
6
7 <script type="text/javascript">
8 function comet(msg){
9 //console.log(msg);
10 var cont = '';
11 cont += "<b>客户端"+msg.name+"</b>\t"+msg.time+"<br/>";
12 cont += msg.content + "<br/>";
13 //console.log(cont);
14 document.getElementById('msgzone').innerHTML += cont;
15 }
16
17 </script>
18 <style type="text/css">
19 #msgzone{
20 border: solid 1px gray;
21 width: 400px;
22 height: 200px;
23 overflow:scroll;
24 }
25 </style>
26 </head>
27
28 <body>
29 <h1> Conmet反向Ajax技术-在线客服系统之服务端 </h1>
30 <h3> 原理:iframe + 长连接获取实时内容,并更新到父页面 </h3>
31 <div id="msgzone">
32
33 </div>
34 <iframe src="commet_iframe.php" width=0px height=0px></iframe>
35 </body>
36
37 </html>
View kefu.html
二、消息交互,管理员回复消息实现
接下来我们来实现管理员回复
1.界面设计
在前面HTML的基础上,加上一个文本框,和一个按钮
界面如图所示:
2.接下来,我们修改comet函数中的代码,让其实现我们点击客户端的姓名时,在回复后面就会自动加上客户端的姓名
如图所示,当我们点击客户端用户名时,在回复后面就会显示用户的名字
3.接下来,就是实现,服务端发送信息了。加入代码
xhr = new XMLHttpRequest(); function huifu(){ var rec = document.getElementById('rec').innerHTML; var cont = document.getElementsByTagName('textarea')[0].value; if(rec == '' || cont == ''){ alert("请选择回复人并填写回复信息"); return; } xhr.open('POST','sendmsg.php',true); xhr.setRequestHeader('content-type','application/x-www-form-urlencoded'); xhr.onreadystatechange = function(){ if(this.readyState == 4){ //alert(this.statusText); if(this.statusText == "OK"){ var rep = ""; rep += "<br/><b><span>服务端admin"+"</span></b>\t"; rep += "<br />"; rep += cont; document.getElementById('msgzone').innerHTML += rep; document.getElementsByTagName('textarea')[0].value=''; } } } xhr.send('rec='+rec+'&content='+cont); } |
4.编写sendmsg.php 在该PHP程序中实现将服务器发送的数据存储进数据库中。
<?php //连接数据库 $conn = mysql_connect('localhost','root',''); mysql_query('use test',$conn); mysql_query('set names utf8',$conn);
$rec = $_POST['rec']; $content = $_POST['content']; $name = $_COOKIE['username'];
$sql = "insert into msg(name,content,rec,isread) values('$name','$content','$rec',1)"; echo mysql_query($sql,$conn)?'ok':'fail';
?> |
5.将kefu.html修改为kefu.php并且加入以下代码:
<?php setcookie('username','admin'); ?> |
6.实现结果如下所示:大功告成,接下来我们的任务就是实现客户端的页面了。
数据库中:
附上当前commet_iframe.php代码:
1 ob_start();
2 <?php
3 ob_clean();
4 set_time_limit(0); //脚本运行不受限制
5
6 //连接数据库
7 $conn = mysql_connect('localhost','root','');
8 mysql_query('use test',$conn);
9 mysql_query('set names utf8',$conn);
10 $msg_tmp = "";
11 while(1){
12 //$sql = 'select * from msg where name ="LoverXueEr" and isread = 0 limit 1';
13 $sql = 'select * from msg where isread = 0 limit 1';
14 $rs = mysql_query($sql,$conn);
15 $msg = mysql_fetch_assoc($rs);
16 if(!empty($msg)){ //若消息不为空
17 //将我们已读取的消息置为已读
18 //$sql = " update msg set isread = 1 where name= '".$msg['name']."' && content= '".$msg['content']."' && num= ".$msg['num'] ;
19
20
21 //格式化我们的消息为一个字符串
22 //$msg_tmp = "<b>".$msg['name']."</b> \t".strftime("%d/%m/%Y %H:%M:%S")."<br/>" . $msg['content'].'<br/>';
23 //json_encode() 自动编码
24 $msg['time']=strftime("%d/%m/%Y %H:%M:%S");
25 $msg_tmp = json_encode($msg);
26 echo '<script type="text/javascript">';
27 //将消息传递给comet函数
28 echo 'parent.window.comet('.$msg_tmp.');';
29 echo '</script>';
30
31 $sql = " update msg set isread = 1 where content= '".$msg['content']."' && num= ".$msg['num'] ;
32 mysql_query($sql,$conn);
33 ob_flush();
34 flush();
35 }
36 sleep(1);
37 }
38 ?>
View commet_iframe.php
附上当前kefu.php代码:
1 <?php
2
3 setcookie('username','admin');
4 ?>
5
6 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
7 <html>
8 <head>
9 <title>在线客服系统之服务端</title>
10 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
11
12 <script type="text/javascript">
13 function comet(msg){
14 //console.log(msg);
15 var cont = '';
16 cont += '<b><span onclick="reply(\''+msg.name+'\')">客户端'+msg.name+"</span></b>\t"+msg.time+"<br/>";
17 cont += msg.content + "<br/>";
18 //console.log(cont);
19 document.getElementById('msgzone').innerHTML += cont;
20 }
21 function reply(name){
22 //console.log(name);
23 document.getElementById('rec').innerHTML = name;
24 }
25 xhr = new XMLHttpRequest();
26 function huifu(){
27 var rec = document.getElementById('rec').innerHTML;
28 var cont = document.getElementsByTagName('textarea')[0].value;
29 if(rec == '' || cont == ''){
30 alert("请选择回复人并填写回复信息");
31 return;
32 }
33 xhr.open('POST','sendmsg.php',true);
34 xhr.setRequestHeader('content-type','application/x-www-form-urlencoded');
35 xhr.onreadystatechange = function(){
36 if(this.readyState == 4){
37 //alert(this.statusText);
38 if(this.statusText == "OK"){
39 var rep = "";
40 rep += "<br/><b><span>服务端admin"+"</span></b>\t";
41 rep += "<br />";
42 rep += cont;
43 document.getElementById('msgzone').innerHTML += rep;
44 document.getElementsByTagName('textarea')[0].value='';
45 }
46 }
47 }
48 xhr.send('rec='+rec+'&content='+cont);
49 }
50
51 </script>
52 <style type="text/css">
53 #msgzone{
54 border: solid 1px gray;
55 width: 400px;
56 height: 200px;
57 overflow:scroll;
58 }
59 </style>
60 </head>
61
62 <body>
63 <h1> Conmet反向Ajax技术-在线客服系统之服务端 </h1>
64 <h3> 原理:iframe + 长连接获取实时内容,并更新到父页面 </h3>
65 <div id="msgzone"></div>
66
67 回复:<span id="rec"></span>
68 <p><textarea></textarea><p>
69 <p><input type="button" value="回复" onclick="huifu();"/></p>
70
71 <iframe src="commet_iframe.php" width=0px height=0px></iframe>
72 </body>
73
74 </html>
View kefu.php
附上当前sendmsg.php代码:
1 <?php
2
3 //连接数据库
4 $conn = mysql_connect('localhost','root','');
5 mysql_query('use test',$conn);
6 mysql_query('set names utf8',$conn);
7
8 $rec = $_POST['rec'];
9 $content = $_POST['content'];
10 $name = $_COOKIE['username'];
11
12 $sql = "insert into msg(name,content,rec,isread) values('$name','$content','$rec',1)";
13 echo mysql_query($sql,$conn)?'ok':'fail';
14
15
16 ?>
View sendmsg.php