web即時聊天系統的實現
第【1】頁
即時通訊方案:ajax輪詢與ajax長輪詢
什麼是ajax?
AJAX (Asynchronous JavaScript and XML) 異步的JavaScript和XML
AJAX 最大的優點是在不重新加載整個頁面的情況下,可以與服務器交換數據並更新部分網頁內容。
如果有人不清楚這個概念可以查看菜鳥教程-AJAX教程,我在此簡單展示一下使用方法。
原生JavaScript
我對ajax進行簡單封裝
function ajax(object) {
var
xhr = window.XMLHttpRequest?(this.ajaxObject ||
new XMLHttpRequest()):new ActiveXObject("Microsoft.XMLHTTP"),
status = true,
responseType=object.dataType || "text";
//onabort中斷事件,onerror錯誤事件,ontimeout超時事件
xhr.onabort = xhr.onerror = xhr.ontimeout = object.error;
//每當 readyState 改變時,就會觸發 onreadystatechange 事件。
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (typeof object.success == "function") {
//如果readyState爲4,執行ajax請求成功的回調函數success
responseType == "text"object.success(xhr.responseText):object.success(xhr.responseXML);
}
}
if (xhr.onabort || xhr.onerror || xhr.ontimeout) {
status = false;
}
}
xhr.timeout = object.timeout || 60000; //自定義超時或默認60s
xhr.open(object.type || 'get', object.url,object.async || true);//設置請求方式
xhr.setRequestHeader("Content-type",object.contentType || "application/x-www-form-urlencoded"); //設置請求頭部
xhr.send(object.data || null); //請求發送Get請求則在url上以參數的形式發送並在send方法傳入參數null
if (status) {
return true;
}
}
使用時傳參
ajax({
url: "****",
data: "****",
type: "post",
success: function(msg){},
error: function() {}
})
jQuery
如果想學習jQuery可以查看菜鳥教程-jQuery教程
比較推薦使用jQuery的ajax方法,jQuery對ajax的封裝非常的完善,常用用法。
$.ajax({
url:'url' //請求地址
type:'post', //請求方式
async:true, //是否異步
data:data, //請求數據
dataType: 'json', //請求發送的數據類型
success:function(data){}, //請求成功執行
error:function(){} //請求錯誤執行
})
上面就是ajax 的用法了,接下來介紹本篇【0-2】重點
ajax輪詢
通過上面我們初步瞭解ajax是什麼東西吧,那我們來了解一下ajax輪詢是什麼東西吧
ajax輪詢也叫ajax短輪詢,客戶端通過計時器事件setInterval函數隔一段事件重複向服務器HTTP請求,服務器端在收到請求後,不論是否有數據更新,都直接進行響應。這種方式實現的即時通信,本質上還是瀏覽器發送請求,服務器接受請求的一個過程,通過讓客戶端不斷的進行請求,使得客戶端能夠模擬實時地收到服務器端的數據的變化。
輪詢的作用就是在獲取服務器上最新的message(用戶之間交流的話我稱爲message)
方案思路:即時通信無外乎兩個點:1.消息獲取 2.消息發送
消息獲取:如果用戶B想從服務器得到用戶A所發送的message,如何即時得到用戶A所發送的message呢,那就是用戶B要隔一段事件反覆請求服務器,以便獲取用戶A存儲在服務器上最新的message。
消息發送:用戶A想回應用戶B,則利用ajax請求將message發送給服務器存儲,等待用戶B的獲取。
消息更新【前端】像這樣調用我所封裝好的ajax函數。通過ajax輪詢反覆發送請求以便獲取最新的message
setInterval(ajax({
url: "****",
data: "****",
type: "post",
success: function(msg){
//將msg反封裝後打印在頁面上實現消息獲取的更新
document.getElementById('result').innerHTML = msg;
},
error: function() {}
}),1000); //1s請求一次
data:你發送的請求的數據,在本次的項目中就是請求獲取【用戶A發送的即時通訊消息】,一般來說
success:回調函數的參數msg就是服務器響應的數據,其中就包含用戶A的message。
消息發送 【前端】
ajax({
url: "****",
data: "****",
type: "post",
success: function(msg){
//獲取響應的code,判斷消息類型,把你發送的message打印在頁面上
if(code == 1){
var myMSG = document.getElementById('sendMSG').value;
document.getElementById('result').innerHTML = myMSG;
}
},
error: function() {}
})
ajax長輪詢
長輪詢的思路跟短輪詢是差不多的,只不過短輪訓是“無腦的”發送請求去獲取更新,即使沒有新的message。
而ajax長輪詢則當服務器收到客戶端發來的請求後,服務器端不會直接進行響應,而是先將這個請求掛起,然後判斷服務器端數據是否有更新。如果有更新,則進行響應,如果一直沒有數據,則到達一定的時間限制(服務器端設置超時)才返回。 客戶端JavaScript響應處理函數會在處理完服務器返回的信息後,再次發出請求,重新建立連接。
【前端】
ajax({
url: "****",
data: "****",
type: "post",
success: function(msg){
//獲得了響應,纔再去獲取數據
ajax();
//將msg反封裝後打印在頁面上實現消息獲取的更新
document.getElementById('result').innerHTML = msg;
},
error: function() {}
})
現階段沒有後端代碼,後端的代碼會在實現篇詳細說明的(emmm腦殼疼,也許沒有,因爲我並不想採用這種方案),現在前端代碼知識幫助我們理解即時通訊方案的原理
優缺點比較
ajax短輪詢的優點是比較簡單,易於理解,實現起來也沒有什麼技術難點。缺點是顯而易見的,這種方式由於需要不斷的建立http連接,嚴重浪費了服務器端和客戶端的資源。尤其是在客戶端,距離來說,如果有數量級想對比較大的人同時位於基於短輪詢的應用中,那麼每一個用戶的客戶端都會瘋狂的向服務器端發送http請求,而且不會間斷。人數越多,服務器端壓力越大,這是很不合理的。
ajax長輪詢和短輪詢比起來,明顯減少了很多不必要的http請求次數,相比之下節約了資源。長輪詢的缺點在於,連接掛起也會導致資源的浪費。
由此得知輪詢對於現在這種網絡時代背景下,是很不理想的實現方案,儘管實現代碼方法簡單。因此我考慮HTML5新技術webSocket方案來實現。
[2019-10-25]