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 ?>
附上当前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>
二、消息交互,管理员回复消息实现
接下来我们来实现管理员回复
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 ?>
附上当前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>
附上当前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 ?>
* 博客园: http://www.cnblogs.com/lihaiyan/
* 邮箱:1063385677@qq.com
* QQ: 1063385677
* Copyright ©2014 Lover雪儿
********************************************
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。