20150220 Comet反向Ajax技術-在線客服系統之服務端 javascript
2015-02-20 李海沿 php
前面咱們講了comet反向Ajax模型原理 以及實現了簡單的實時頁面聊天系統。 css
(地址:http://www.cnblogs.com/lihaiyan/p/4281049.html) html
本文中,咱們在它的基礎上來實現一個在線客服系統的服務端。 java
1、搭建頁面客服系統框架 mysql
1.首先新建一個kefu.html網頁 sql
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">數據庫 <html>json <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>
2、消息交互,管理員回覆消息實現
接下來咱們來實現管理員回覆
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 ?>