本帖最後由 stneo1990 於 2013-08-08 11:45:06 編輯
首先,這是一個仿客服諮詢的即時通訊系統,主要目的是將類比前台使用者發送的訊息(通過手動INSERT進MYSQL資料庫實現)由伺服器即時推送到前台客服頁面上,大致結構如下:
1、在前台kefu.html頁面上有一個iframe,這個iframe請求後台query.php查詢程式(iframe在頁面上隱藏了)
2、query.php通過一個while(true)死迴圈並設定set_time_limit(0),然後,在迴圈中不斷的進行SQL查詢,將使用者發送的未讀的訊息查詢出來,並通過輸出JS代碼,操作父頁面的區,將查詢出來的訊息結果輸出到頁面上
3、我通過手動INSERT一些資料,來類比使用者的訊息提交, 預設訊息是未讀狀態,當query.php讀取後,會改變其為已讀狀態
現在的問題是:當我開啟頁面後(或者關閉頁面再重新開啟程式),一般最開始插入的資料都不能被顯示到頁面上,但是這些訊息的狀態卻已經被query.php改為已讀(也就是query.php已經查詢到這條記錄並發送JS代碼到前端了),而當我繼續插入很多條之後,前端才開始顯示記錄,並且之前INSERT的記錄都是被標示讀取狀態了,但是卻沒有顯示到前台kefu.html頁面上,要插入很多條之後,或者等一段時間後才能恢複正常
整個程式並沒有問題,因為之後的程式就是正常的可以一條一條顯示了,插入一條前台就顯示一條(但是偶爾中途也會丟失一條)
我猜測問題的根源可能有兩點:
1、PHP的指令碼並沒有被結束
2、JS可能有緩衝導致雖然接收到了資料,但沒有更新
不過以上兩點我都不確定,我覺得可能問題沒這麼簡單,應該是違反或者沒有注意某個機理而造成的。
具體代碼如下,還請各位幫忙看看問題出在了什麼地方,也可以本地測試下,謝謝了。
測試方法:
手動在資料庫中INSERT資料,然後觀察前台kefu.html頁面是否能及時收到並更新訊息
資料庫建表:
CREATE TABLE msg(
id int(11) NOT NULL auto_increment,
pos varchar(20) NOT NULL default '',
rec varchar(20) NOT NULL default '',
content varchar(200) NOT NULL default '',
isread` int(1) NOT NULL default '0',
PRIMARY KEY(id)
);
插入資料樣本:
insert into msg(rec,pos,content,isread) values('admin','zhangsan','hello',0);
回複討論(解決方案)
前台kefu.html代碼:
線上客服系統 線上客服系統--客服端
回複:
後端查詢query.php代碼:
';ob_flush();flush();$i = 0;require 'conn.php';//串連資料庫檔案//不斷迴圈查詢訊息while(true){//查詢接收者為admin,並且是未讀的訊息$sql = 'select * from msg where rec = "admin" and isread = 0 limit 1';$result = $conn -> query($sql);//提取查詢結果$rs = $result -> fetch_assoc();if(!empty($rs)){//將這條訊息更新為已讀狀態$sql = 'update msg set isread = 1 where id = "'.$rs['id'].'" limit 1';$conn -> query($sql);//轉換為JSON格式準備發送給JS$rs = json_encode($rs);//通過paren調用父表單的comet()函數,並將轉換的JSON資料傳送過去,comet()函數可以在kefu.html代碼中找到echo '';}ob_flush();flush();//防止查詢次數過多,設定的每1秒查詢一次sleep(1);}
資料庫連接conn.php代碼:
query('set names utf8');
建議還是採用AJAX的輪詢方式,這種的後台查詢指令碼裡沒有主動結束指令碼執行,可能存在一定問題。
我測試的是只能顯示一個 後面的都顯示不出來