20150220 Comet反向Ajax技术-在线客服系统之服务端

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

 

php开发客服系统。真正的实时聊天,使用持久连接+轮询+反向ajax实现 用户端(可直接给客户发送消息) 客服端(点击用户名.即可给该用户回复消息) 讲两种实现方式: 一:iframe + 服务器推技术comet(反向ajax,即服务器向浏览器推送数据) 二:ajax持久连接 + 长轮询 客服端采用第一种方式:iframe + 服务器推技术 思路: 1:新建comentbyiframe.php 该用文件使用while(true)一直连接到服务器不断开. 如果在while的过程中查到了新数据.使用ob_flush推给apache服务器.apache再用flush推给浏览器. 2:新建html页面,插入一个iframe. 该iframe的src为comentbyiframe.php。 并隐藏iframe。comentbyiframe.php获取的数据用js输出到父窗口中的某个函数.该函数把信息追加到指定的聊天窗口中 3:只要客户端收到用户发来的数据. 就显示为"xx对你说..". 客服端只要点击用户名。即可给该用户发送数据. 用户端采用第二种方式:ajax持久连接 + 长轮询 ajax持久连接:文档加载完毕后(或其他时机),使用ajax请求一个php文件 被请求的php文件通过while(true)循环.迟迟不给apache返回数据的目的. 轮询指:请求服务器的时候.如果服务器没有数据.则一直等.当服务器有数据后.就返回给客户端. 这样请求、响应过后就完成了一次HTTP请求. 还没完.客户端收到数据后又到服务器要数据.这就是轮询 就好像一个乞丐一样. 不给他钱,他就一直跟着你要. 你给他钱以后.他还不满足,又跑来找你要. 实现思路: 进入用户端后.如果没有用户名.使用setcookie设置一个用户名.然后通过ajax持久连接. 不停向服务器索要数据(即客服发送给该用户的记录). 详情:http://www.phpyan.com/home/article/350.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小馋喵星人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值