萬盛學電腦網

 萬盛學電腦網 >> 網頁制作 >> 腳本Html教程 >> Http環境下的保持連接方式

Http環境下的保持連接方式

   Http環境本身是一種無連接狀態的架構,在這種架構下服務器只能是被動的接受客戶端的請求,返回結果,而無法主動的給客戶端發送數據。而在很多需要實時數據交互(比如Web IM)的場景中,我們卻希望能及時得到服務器給我們返回的數據。此時,一種最為普遍的做法是:在客戶端用定時器,定時去請求服務器的服務,來得到最新數據。而這樣一來,很多時候卻是在做無用功,頻繁的請求也會無端的增加服務器和客戶端在請求Web服務上的消耗。那麼是否有一種更好的辦法,既可以及時得到服務器的返回,同時又可以減少做無用功,以及頻繁請求帶來的性能問題呢?

  記得前不久,在園子裡有這樣的一篇文章,介紹了幾種WEB環境定時刷新數據的機制。其中就有提到google gmail的一種比較巧妙的做法,現在記不得當時是怎麼理解這種做法了,只記得有“保持長連接”的基本做法。(當然現在也找不到這篇文章了,希望了解的朋友能提醒一下)。今天由於架構方案的需要,再來仔細思考連接保持方案,以及參考gmail的請求行為,總結了一下,應該是這樣的:客戶端一直保持一個與服務器的連接,這個連接一直保持著對服務器的請求動作,直到服務器發現有數據後給它返回後,才結束返回這一次請求。客戶端在接收到請求返回後,在處理這些返回之前,又向服務器發送了一次連接請求,直到下一次有數據返回。不可避免的有一種情況,就是如果服務器長時間沒有需要給客戶端發送數據的話,那麼可以就會造成請求失敗(超時或其它原因)。對於這種情況的處理也是一樣的,在錯誤的回調事件中重新發送一次請求連接。這樣就可以模擬保持連接狀態了。

  用偽代碼來描述一下思路吧:

  客戶端腳本:

  1: function Request()

  2: {

  3: Ajax.Request(url,OnSuccessed,OnFailed);

  4: }

  5: function OnSuccessed(response)

  6: {

  7: //重新發送一次請求

  8: Request();

  9: //處理返回數據

  10: }

  11: function OnFailed()

  12: {

  13: //錯誤(超時)重新請求

  14: Request();

  15: }

  Web服務:

  1: public class IMService : IHttpHandler

  2: {

  3: public bool IsReusable{return false;}

  4: public void ProcessRequest(HttpContext context)

  5: {

  6: //讀取最新數據

  7: while(true)

  8: {

  9: string message = GetMessage();

  10: if(!string.IsNullOrEmpty(message))

  11: {

  12: context.Response.Write(message);

  13: break;

  14: }

  15: Thread.Sleep(500);//等待一段時間再重新讀取。

  16: }

  17: }

  18: private string GetMessage()

  19: {

  20: //取得最新數據

  21: }

  22: }

  這種方案的好處有:客戶端可以第一時間得到服務器需要給客戶端發送的數據(而至於Web服務怎麼知道要給客戶端發送數據,也就是服務器的輪循設計,則是另一個需要考慮的方案);可以減化客戶端邏輯,無需要創建和釋放定時器,並減小由此產生的對客戶端性能的損失;減少去服務器的請求次數,減少做無用功,節約節省帶寬和減少服務器資源需要處理的連接請求。

  相信在此之前,已經有很多人在使用這種方案了。歡迎大家就此方案發表自己的見解。

  補充:服務器部分的設計,除了使用輪循外,也可以考慮使用資源互斥訪問的方式來設計,這樣做可以獲得更佳性能,更高實時性,具體的方案應當根據實際情況來考慮。

copyright © 萬盛學電腦網 all rights reserved