Ajax-客户客服聊天系统

Web 通信 之 长连接、长轮询(long polling)
基于HTTP的长连接,是一种通过长轮询方式实现”服务器推”的技术,它弥补了HTTP简单的请求应答模式的不足,极大地增强了程序的实时性和交互性。

1.
轮询:客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接。
优点:后端程序编写比较容易。
缺点:请求中有大半是无用,浪费带宽和服务器资源。
实例:适于小型应用。

2.
长轮询:客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。
优点:在无消息的情况下不会频繁的请求,耗费资源小。
缺点:服务器hold连接会消耗资源,返回数据顺序无保证,难于管理维护。
实例:WebQQ、Hi网页版、Facebook IM。

3.
长连接:在页面里嵌入一个隐蔵iframe,将这个隐蔵iframe的src属性设为对一个长连接的请求或是采用xhr请求,服务器端就能源源不断地往客户端输入数据。
优点:消息即时到达,不发无用请求;管理起来也相对方便。
缺点:服务器维护一个长连接会增加开销。
实例:Gmail聊天

实例代码:
客服端:
<1>AJ04custserv.php

<?php
setcookie('username','admin');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">
<head>
<title>新建网页</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">

//在客服系统端打印用户发送的的信息,msg是在AJ04server.php
//中封装过的数据,可以直接访问
function comet(msg){
   var cont ='';
   cont += '<a onclick="replay(\''+msg.pos+'\')">'+msg.pos +'</a>'+'对你说<br />';
   cont += msg.content+'<br />';
    document.getElementById('msgzone').innerHTML +=cont;
}

//点击不同用户名的响应事件
function replay(pos){
  document.getElementById('rec').innerHTML=pos;
}

//发送信息到用户
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','AJsendmsg.php',true);
    //设置头信息
    xhr.setRequestHeader('content-type','application/x-www-form-urlencoded');
    //根据服务器端的状态码执行回调函数
    xhr.onreadystatechange=function(){
       if(this.readyState==4){
         if(this.responseText=='OK'){
        //接受数据成功需要执行的操作
        var rep ='';
        rep += '你对'+rec+'说<br />';
        rep += cont+'<br />';
        //在网页上打印信息
        document.getElementById('msgzone').innerHTML+=rep;
        //清空对话框信息
        document.getElementsByTagName('textarea')[0].value='';         
         }
       }
    }
    xhr.send('rec='+rec+'&content='+cont);
}
</script>

<style type="text/css">
#msgzone{
  border: 1px solid gray;
  width:300px;
  height:400px;
  overflow:auto;
}
</style>
</head>
    <body>
    <h1>Ajax实时聊天之客服系统</h1>
    <h2>iframe+长连接,获取实时内容,返回到主界面</h2>

    <div id="msgzone">
    </div>

    回复:<span id="rec"></span>
    <textarea></textarea>
    <input type="button" value="回复" onclick="huifu();">
    <p><iframe src="AJ04serve.php" width="0" height="0" iframeBorder="0"></iframe></p>
    </body>
</html>

<2>AJ04serve.php

<?php

//永久执行直到程序结束
set_time_limit(0);
//导入连接数据库的代码
require('./AJconn.php');

//客服端一直在监听的事件
while(true){
        //从数据库中读取rec="admin" and isread=0'的客服的对话数据
         $sql='select * from msg where rec="admin" and isread=0';
         //使用mysql_query读取内容
         $rs=mysql_query($sql,$conn); 
         //取得结果集的一行并放入数组中
         $msg=mysql_fetch_assoc($rs); 
         if(empty($msg)){
         }else{
        //更新数据库中isread=0的行改为isread=1
        $sql='update msg set isread=1 where mid='.$msg['mid'].' limit 1';
        //使用mysql_query更新内容内容
        mysql_query($sql,$conn);
        //使用json_encode()将php数据封装在js中,以在js中访问
        $msg=json_encode($msg);
        echo '<script type="text/javascript">';
        echo 'parent.window.comet('.$msg.');';
        echo '</script>';
        //强迫php把内容发给Apache
        ob_flush(); 
        //强迫apache发给浏览器      
        flush();           

 }

 sleep(1);
}
?>

客户端:
<3>AJ05customer.php
(方式一)使用本地jQuery库
我使用的是本地的jquery.js,可以在地址栏里输入链接
//libs.baidu.com/jquery/1.7.2/jquery.min.js,复制内容保存为jquery.js

<script type="text/javascript" src="jquery.js"></script>

(方式二)使用远程jQuery链接库

<script type="text/javascript" src="//libs.baidu.com/jquery/1.7.2/jquery.min.js"></script>
<?php
//对于每一个新进入的用户进行编号
if(empty($_COOKIE['username'])){
setcookie('username','admin'.rand(100,999));
}
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">
<head>
<title>新建网页</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="jquery.js"></script>

<script type="text/javascript">
function xunwen(){
    //获取对话框中发送的数据
    var cont=$('textarea:first').val();
    //将数据提交到AJsendmsg.php,根据回调函数,将信息显示在屏幕上
    $.post('AJsendmsg.php',{rec:'admin',content:cont},function(res){
        if(res=='OK'){
        $('<p>你对客服说<br />'+cont+'</p>').appendTo($('#msgzone'));
        //将发送信息的文本框内的数据清空,体现发送数据的动态效果
        $('textarea:first').val('');
        }

    });
}
</script>

<style type="text/css">
#msgzone{
  border: 1px solid gray;
  width:300px;
  height:400px;
  overflow:auto;
}
</style>
</head>
    <body>
    <h1>Ajax顾客系统</h1>
    <h2>iframe+长连接+长轮询获取实时内容,返回到主界面</h2>

    <div id="msgzone">
    </div>

    <textarea></textarea>
    <input type="button" value="询问" onclick="xunwen();">
</body>


<script type="text/javascript">
    //接受来自客服的信息
    var setting={url:'AJ05comitajax.php',
        dataType:'json',
        success:function(res){
        // 每隔一秒返回一次数据,并继续监听
        window.setTimeout(function(){$.ajax(setting)},1000);
        //将接受的数据显示在对话框中
        $('<p>客服对你说<br/>'+res.content+'</p>').appendTo($('#msgzone'));
        }
    };
        $.ajax(setting);
</script>


</html>

<4>AJ05comitajax.php

<?php

// 永久执行直到程序结束
set_time_limit(0);
//导入连接数据库的代码
require('./AJconn.php');

//从COOKIE中获取用户username
$rec=$_COOKIE['username'];
//遍历数据库接受者是用户的信息且isread=0
$sql="select * from msg where rec='$rec' and isread=0 limit 1";

//客户端一直在监听的事件
while(true){
    //执行sql语句
    $rs=mysql_query($sql,$conn);
    //找出结果集符合条件的一条字段集
    $row=mysql_fetch_assoc($rs);
    if(!empty($row)){
        //跟新数据库数据isread=1
        $sql="update msg set isread=1 where mid=" . $row['mid'];
        mysql_query($sql,$conn);
        //对结果集进行json格式的编码,便于数据传输和利用
        echo json_encode($row);
        exit();

    }

    //减轻服务器负担
    sleep(1);
}
?>

<5>.连接数据库:conn.php

<?php

//连接数据库
$conn=mysql_connect('localhost','root','');
mysql_query('use test',$conn);
mysql_query('set names utf8',$conn);

?>

<6>.将聊天信息插入数据库:AJsendmsg.php

<?php

//将消息插入数据库
require('./AJconn.php');

$rec=$_POST['rec'];
$content=$_POST['content'];
$pos=$_COOKIE['username'];

$sql="insert into msg(rec,pos,content) values('$rec','$pos','$content')";

echo mysql_query($sql,$conn)?'OK':'FIAL';


?>

》》》目录视图
这里写图片描述

》》》数据库准备
这里写图片描述

》》》效果展示
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值