最近做了一个简单客服系统
具体过程:
一、服务端
测试环境为wamp
首先建立一个简单数据库,如下:rec为接受者,pos为发送者,content为发送内容isread为0则表明未读,否则表明已经读过,我们在页面中显示的将是未读的content,一旦显示过,就会更新数据库,将其isread更新为1。因为客户端还没建立,通过cmd来往数据库中插入数据
服务端使用了服务器推的技术,利用iframe来刷新服务端页面,服务器中不断查询数据库中pos为admin且isread为0的数据,如果有则利用iframe刷新,将数据添加到页面上,代码如下:
filename : cometByIframe.php
<?php
/*filename : cometByIframe.php*/
set_time_limit(0);
ob_start();
echo str_repeat(' ',4000),"<br />";
ob_flush();
flush();
require('./conn.php');//链接的数据代码
$i = 0;
while(true){
echo str_repeat(' ',4000),"<br />";
// $i++;
$sql = 'select * from msg where rec = "admin" and isread=0';
$res = $conn->query($sql);
$msg = $res->fetch_assoc();
if(empty($msg)){
// echo "Empty";
}else{
//insert into msg (rec,pos,content) values('admin','list','nihao');
$sql = 'update msg set isread=1 where mid='.$msg['mid'].' limit 1';
$conn->query($sql);
print_r($msg);
$msg = json_encode($msg);
echo '<script type="text/javascript">';
echo "parent.window.comet(".$msg.")";
echo "</script>";
//echo $msg;
// echo str_repeat(' ',4000),"<br />";
ob_flush();//强迫php把内容发给apache
flush();//强迫webserver把内容发送给浏览器
}
sleep(1);
}
?>
其将数据通过script的代码推送到页面显示,其页面显示如下:
</pre>filename : cometByIframe.php<p></p><p></p><pre name="code" class="php"><?php
setcookie('username','admin');
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>customer</title>
<script type="text/javascript" src="http://libs.baidu.com/jquery/1.9.0/jquery.min.js"></script>
<script type="text/javascript">
function comet(msg){
// alert(msg);
var cont = "";
cont +='<span οnclick="selectReply(this)">'+msg.pos+'</span>'+"对你说<br/>";
cont +=msg.content+"<br/>";
// alert(cont);
document.getElementById("msgzone").innerHTML +=cont;
}
function selectReply(obj) {
// alert(obj.innerHTML);
// console.log(obj);
document.getElementById("rec").innerHTML = obj.innerHTML;
}
function reply(){
var reciver = $("#rec").text();
var content = $("#content").val();
// alert(reciver);
// alert(content);
if(reciver && content){
$.post("./sendMsg.php",
{
rec:reciver,
content:content
},
function(data,status){
// alert(data);
var rep = '';
rep += '你对'+reciver+'说</br>';
rep += content+'<br/>';
document.getElementById("msgzone").innerHTML += rep;
$('#content').val(null);
});
}else{
alert("请选择回复人并填入留言内容");
}
}
</script>
<style type="text/css">
#msgzone{
width: 500px;
height: 300px;
border: 1px solid gray;
overflow :auto;
}
</style>
</head>
<body>
<h1>comet反向ajax技术--在线客服系统--客服端</h1>
<h2>特点:界面粗糙,技术不粗糙</h2>
<h3>原理:iframe+长链接,获取实时内容,并更新到父页面</h3>
<div id="msgzone"></div>
回复:<span id="rec"></span>
<p><textarea id ="content"></textarea></p>
<input type="button" value="回复" οnclick="reply()"></input>
<iframe src="cometByIframe.php" width="0px" height="0px" frameborder="0px"></iframe>
</body>
</html>
filename ; conn.php
<?php
// header('content-type:text/html;charset=utf-8');
$conn = new mysqli("127.0.0.1","root","bngd1223","chat");
if(mysqli_connect_errno()){
die('Unable to connect!'.$conn->connect_errno.':'.$conn->connect_error);
}else{
$conn->set_charset('UTF8');
}
?>
服务器端还有一个回复的功能,其后台代码
filename :sendMsg.php
<?php
require("./conn.php");
$rec = $_POST['rec'];
$content = $_POST['content'];
$pos = $_COOKIE['username'];
//print_r($rec);
$sql = "insert into msg (rec,pos,content) values('$rec','$pos','$content')";
$res = $conn->query($sql);
if($res){
echo "send success";
}else{
echo "send fail".$conn->errno.":".$conn->error;
}
?>
二、客户端
客户端的回复的后台逻辑和服务器一样的,代码为sendMsg.php
客户端等待服务端响应的过程为ajax长轮询,其利用jquery中的ajax的递归
$(function(){
var setting ={
url:"cometByAjax.php",
success:function(data,status){
console.log(data.content);
$("<p>客服对你说<br/>"+data.content+"</p>").appendTo($('#msgzone'));
$.ajax(setting);//递归
},
dataType:'json'//返回值类型
};
$.ajax(setting);
});
cometByAjax.php是一直轮询数据库,来看是否有该用户的未读留言,如果有,则返回200OK,然后回调函数将留言内容加到当前div上,然后继续挂起ajax进行轮询,此时如果服务端给客户端发送一条消息,那么这条消息首先经过服务器的sendMsg.php被存入数据库中,而此时客户端又在轮数据库,然后检测到这条数据符合要求,然后就返回调用回调函数,然后回调函数中继续挂起ajax然后就这样一直轮下去。就是说,客户端对数据库一直在轮询,数据库中一旦出现符合条件的数据,便结束循环,然后到回调函数中又一次开始轮询。
filename : cometByAjax.php
<?php
// echo json_encode(array('content' => 'af'));
// exit;
set_time_limit(0);
require('./conn.php');
$res = $_COOKIE['username'];
$sql = "select * from msg where rec = '$res' and isread=0 limit 1";
while(true){
$res = $conn->query($sql);
if($res){
$arr = $res->fetch_assoc();
if(!empty($arr)){
echo json_encode($arr);
$sql = 'update msg set isread=1 where mid='.$arr['mid'].' limit 1';
$conn->query($sql);
exit();
}else{
// echo "empty";
}
}else{
echo "send fail".$conn->errno.":".$conn->error;
}
sleep(1);
}
?>
轮询时访问的后台代码如下:
filename:cometByAjax.php
<?php
// echo json_encode(array('content' => 'af'));
// exit;
set_time_limit(0);
require('./conn.php');
$res = $_COOKIE['username'];
$sql = "select * from msg where rec = '$res' and isread=0 limit 1";
while(true){
$res = $conn->query($sql);
if($res){
$arr = $res->fetch_assoc();
if(!empty($arr)){
echo json_encode($arr);
$sql = 'update msg set isread=1 where mid='.$arr['mid'].' limit 1';
$conn->query($sql);
exit();
}else{
// echo "empty";
}
}else{
echo "send fail".$conn->errno.":".$conn->error;
}
sleep(1);
}
?>
客户端页面代码:
filename :customer.php
<?php
if(empty($_COOKIE['username'])){
setcookie('username','user'.rand(10000,99999));
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>customer</title>
<style type="text/css">
#msgzone{
width: 500px;
height: 300px;
border: 1px solid gray;
overflow :auto;
}
</style>
<script type="text/javascript" src="http://libs.baidu.com/jquery/1.9.0/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
var setting ={
url:"cometByAjax.php",
success:function(data,status){
console.log(data.content);
$("<p>客服对你说<br/>"+data.content+"</p>").appendTo($('#msgzone'));
$.ajax(setting);//递归
},
dataType:'json'//返回值类型
};
$.ajax(setting);
});
function ask() {
var cont = $('textarea:first').val();
$.post('sendMsg.php',
{
rec:'admin',
content:cont
},
function(data,status){
// alert(data);
if(data == "send success"){
var newP = $("<p>你对客服说<br/>"+cont+"</p>");//在留言界面上添加问题内容
$('#msgzone').append(newP);
cont = $('textarea:first').val('');
}else{
}
});
}
</script>
</head>
<body>
<h1>comet反向ajax技术--在线客服系统--之用户端</h1>
<h3>原理:ajax+长轮询,获取实时内容,并更新到父页面</h3>
<div id="msgzone"></div>
回复:<span id="rec"></span>
<p><textarea id="queryContent"></textarea></p>
<input type="button" value="询问" οnclick="ask()"></input>
</body>
</html>