2009-07-20 97 views
6

我有基於服務器響應更新頁面的AJAX應用程序。 AJAX服務器響應所基於的命令需要很長時間才能生成完整響應,但一旦計算完成,它就會發送部分信息。該部分響應/部分信息以「突發」發送,並且每個突發的時間和大小是不可預知的。將命令輸出流式傳輸到Web瀏覽器(對AJAX請求)的CGI腳本(在Perl中)啓用了自動刷新功能。在AJAX中處理增量服務器響應(在JavaScript中)

服務器響應基於外部命令的輸出。雖然'time cmd>/dev/null'的平均時間約爲10.0秒,'time cmd | head>/dev/null'的時間少於0.1秒(例如數據),所有的數據都是單次調用這個外部命令的結果。

的情況如下所示(ASCII藝術圖如下)

client |  | server 
---------  --------- 

request -\ 
      \ 
      \ 
      \ 
      \-> 

      /- response 
      / . 
     /  . 
     //- . 
     <-// . 
     /  . 
     //- [end] 
     <-//
     /
     /
     <-/ 

我對這個問題的一些問題

注:服務器端爲已完成Perl中的CGI腳本,我寧願看到(也)沒有你的解決方案像jQuery一樣唱歌JavaScript庫/框架。

  • AJAX應用服務器端使用的命令的輸出是基於行的。每一組行以一種定義的行開始,並以其他種類的行結尾,由獨立和不可更改的數據組成。我是否應該將命令的響應作爲'text/plain'並在客戶端使用JavaScript進行處理,還是應該在服務器上預處理數據,並使用'application/json'mimetype將整個數據塊作爲JSON發送?

  • 可能發生的情況是,服務器一次發送的大塊數據很快就會被另一塊數據發送。 onreadystatechange處理程序在前一次調用未完成時調用時如何處理情況?我應該使用全局變量作爲信號量,還是傳遞狀態變量作爲處理程序參數(以及使用xhr.onreadystatechange = function() { handleRequest(xhr, state) })?

  • 我應該使用'text/plain'還是'application/json',或者可能是'multipart/x0mixed-replace'?注意:這個應用程序應該在任何瀏覽器中運行。

  • 如何處理僅在收到完整響應後調用onReadyStateChange的Web瀏覽器(JavaScript引擎)(所以我沒有看到xhr.readyState == 3,即部分響應不止一次)?那麼,除了使用一些JavaScript框架。

  • 如何處理不完整的答案(在這種情況下意味着不完整的行)。

  • 我應該發送響應標記的結束還是依靠計數器來檢查我們是否收到所有數據,或者我可以簡單地依靠檢測xhr.readyState == 4

即使部分響應也會有幫助。

回答

0

我認爲客戶端可以設計爲處理數據塊,發送重複的AJAX請求,直到提供所有數據。這假定即使整個響應很大,每個塊都可以及時發送(沒有客戶端超時問題);並且這種設計可能比開發針對特定的部分響應狀態的檢查更簡單,這些狀態可能因瀏覽器而異。

根據你是否處理服務器端或客戶端,這取決於例如,您需要維護多少個併發客戶端,以及您是否可以使用緩存來處理任何響應;在一些有很多客戶的情況下,最好將一些處理負載分配給他們(當然,只要他們能處理它)。

+1

重複AJAX請求(長輪詢策略)的問題是數據是由_single_命令生成的,所以AJAX的服務器部分必須保存狀態/記住客戶端/傳遞狀態以發送更多請求。 – 2009-07-20 21:58:11

1

我認爲Comet是您所需解決方案的一部分。你可以另外(如果我有這個權利)結帳由Dojo基金會實施的Bayeux Protocol。整個事情還是非常新的(儘管其中的一些可能是第一個HTML5實現的可能)。

除此之外,您可能必須實施輪詢方法。另一個問題是,客戶端JavaScript解釋器可以處理多少數據。你有沒有可能以某種方式「分頁」你的數據,這樣你就不會有處理請求的問題仍然處理,而另一個響應已經進入?