web長連結技術個人總結

Singular_Tech發表於2015-09-15

目的

我個人的目的是為了實現web上的及時通訊,即在網頁上實現即時聊天的效果。這種最簡單來理解的話,可以使用短連結來實現。

1、短連結:jquery/php/mysql

jquery

function link(){
  $.ajax({
    url:"link.php",
data:{yourdata},
type:"post",
success:function(json){
alert(typeof data);
doingsomeing
}
});
settimeout("link()",5000);
}
link();

php

<?php

//資料庫資訊
$data=$_POST['data'];
$result=mysql_query("where $data ...");
//根據上傳來的資訊比如時間等引數查詢資料庫
echo json_encode($result);
上邊的程式碼無法直接使用,只是整理大概的思路。即JS通過settimeout函式不斷的重新執行即向後臺傳送請求,後臺接收到請求後根據條件查詢然後返回結果。

這種方法非常好理解,但是問題是,不斷的請求浪費資源,且資訊不是即時的。

2、長連結:jquery/php/mysql

var ajaxdata={

url:'',

data:'',

type:'',

timeout:30000,

success:function(json){

doingsomeing

$.ajax(ajaxdata);

},

error:function(){

$.ajax(ajaxdata);

}

};

$.ajax(ajaxdata);


php

<?php

...

$i=0;
set_time_limit(0);

while(true){

usleep(500000);//延遲0.5s
$i++;
$result=mysql_query();
if($result){
$this->ajaxReturn($result,"JSON");
break;
}

if($i>=$out_time){
$msg['success']='0';
$msg['text']='';
$this->ajaxReturn($msg,"JSON");
break;
}

}


我起初認為這種長連結 其實並沒有真正的解決短連結的問題,因為有兩個問題,

一、當success或者error之後,會重新再次建立新連線(這個在ajax上必然的,每當一個資訊從PHP返回,則發起這個資訊從發起到返回已經結束了,這個ajax請求會自動結束,必須重新傳送一個新的請求)。

二、在php部分是每間隔多少時間去不斷的請求資料庫。等於把前端的短輪詢搬到了伺服器上。


新手的想法:我們真正想要達到的完美的長連結,應該是前端每30秒傳送一次請求,然後php端跟mysql也建立長連結,mysql資料有更新之後,php返回給js。

這中間會牽涉到js的連結問題,apache中keepalive以及keepalivetimeout的設定,php connect mysql的方法,query的方法。

目前還在尋找方法中,以上僅僅為個人暫時的理解,本人新手。解決之後會再次更新。


3、comet

Ajax本身是無法滿足即時通訊等富互動式應用的實時更新資料的要求的。根本原因是這種瀏覽器端的技術畢竟還是基於http協議,http協議要求的請求/響應的模式也是無法改變的,除非http協議本身有所改變。

以即時通訊為代表的web應用程式對資料的Low Latency要求,傳統的基於輪詢的方式已經無法滿足,而且也會帶來不好的使用者體驗。於是一種基於http長連線的“伺服器推”技術便被hack出來。這種技術被命名為Comet,這個術語由Dojo Toolkit 的專案主管Alex Russell在博文Comet: Low Latency Data for the Browser首次提出,並沿用下來。

其實,伺服器推很早就存在了,在經典的client/server模型中有廣泛使用,只是瀏覽器太懶了,並沒有對這種技術提供很好的支援。但是Ajax的出現使這種技術在瀏覽器上實現成為可能, google的gmail和gtalk的整合首先使用了這種技術。隨著一些關鍵問題的解決(比如 IE 的載入顯示問題),很快這種技術得到了認可,目前已經有很多成熟的開源Comet框架。

comet的實現主要有兩種方式,

1)基於ajax的長輪詢(longpoll)方式

即瀏覽器發出請求,伺服器直到有的新的訊息之後再次返回,按照ajax長輪詢或者ajax長連結能夠搜尋到很多相關的文章,這裡邊有個比較嚴峻的問題就是,當使用長連結,PHP後臺查詢資料更新所用到的不斷查詢,會鎖表導致其他丟該資料的更新請求操作無法進行。

我使用的mysql,嘗試更換引擎型別無效。

使用伺服器端的資料快取,而放棄使用資料庫則太伺服器壓力太大,而且吃力不討好,放棄。下邊方法2中的iframe會導致瀏覽器一直有個小圓圈兒轉到表示正在載入,雖然部分瀏覽器支援htmlfile可以消除,但是不支援的瀏覽器則無法做到,所以綜合考慮,還是使用websocket吧。


2)iframe和htmlfile的流(http streaming)方式

Iframe是html標記,這個標記的src屬性會保持對指定伺服器的長連線請求,伺服器端則可以不停地返回資料,相對於第一種方式,這種方式跟傳統的伺服器推則更接近。

在第一種方式中,瀏覽器在收到資料後會直接呼叫JS回撥函式,但是這種方式該如何響應資料呢?可以通過在返回資料中嵌入JS指令碼的方式,如“<script type="text/javascript">js_func(“data from server ”)</script>”,伺服器端將返回的資料作為回撥函式的引數,瀏覽器在收到資料後就會執行這段JS指令碼。

但是這種方式有一個明顯的不足之處:IE、Morzilla Firefox 下端的進度欄都會顯示載入沒有完成,而且 IE 上方的圖示會不停的轉動,表示載入正在進行。Google 的天才們使用一個稱為“htmlfile”的 ActiveX 解決了在 IE 中的載入顯示問題,並將這種方法應用到了 gmail+gtalk 產品中。


4、Websocket---未來的解決方案

         如果說Ajax的出現是網際網路發展的必然,那麼Comet技術的出現則更多透露出一種無奈,僅僅作為一種hack技術,因為沒有更好的解決方案。Comet解決的問題應該由誰來解決才是合理的呢?瀏覽器,html標準,還是http標準?主角應該是誰呢?本質上講,這涉及到資料傳輸方式,http協議應首當其衝,是時候改變一下這個懶惰的協議的請求/響應模式了。

W3C給出了答案,在新一代html標準html5中提供了一種瀏覽器和伺服器間進行全雙工通訊的網路技術Websocket。從Websocket草案得知,Websocket是一個全新的、獨立的協議,基於TCP協議,與http協議相容、卻不會融入http協議,僅僅作為html5的一部分。於是乎指令碼又被賦予了另一種能力:發起websocket請求。這種方式我們應該很熟悉,因為Ajax就是這麼做的,所不同的是,Ajax發起的是http請求而已。 

與http協議不同的請求/響應模式不同,Websocket在建立連線之前有一個Handshake(Opening Handshake)過程,在關閉連線前也有一個Handshake(Closing Handshake)過程,建立連線之後,雙方即可雙向通訊。


綜上所述,推薦websocket或者comet方法。


相關文章