最近做了一個簡單客服系統
具體過程:
一、服務端
測試環境爲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>