問題描述
我有基于服務器響應更新頁面的 AJAX 應用程序.AJAX服務器響應所基于的命令需要很長時間才能生成完整的響應,但是一旦計算出來它就會發送部分信息.此部分響應/部分信息以突發"形式發送,并且每個突發的時間和大小是不可預測的.將命令輸出流式傳輸到 Web 瀏覽器(到 AJAX 請求)的 CGI 腳本(在 Perl 中)已打開自動刷新.
I have AJAX app which updates page based on server response. The command that AJAX server response is based on takes long time to generate full response, but it sends partial information as soon as it is calculated. This partial response / partial info is send in "burst", and time and size of each burst is unpredictable. CGI script (in Perl) that streams command output to web browser (to AJAX request) has autoflush turned on.
服務器響應基于外部命令的輸出.'time cmd >/dev/null' 平均給出大約 10.0 秒,'time cmd | head >/dev/null' 給出不到 0.1 秒(例如數據).所有數據都是單次調用此外部命令的結果.
The server response is based on output of external command. While 'time cmd > /dev/null" gives around 10.0 seconds on average, 'time cmd | head > /dev/null' gives less than 0.1 seconds (for example data). All data is result of single call to this external command.
情況如下(ASCII-藝術圖如下):
client | | server
--------- ---------
request -
->
/- response
/ .
/ .
/ /- .
<-/ / .
/ .
/ /- [end]
<-/ /
/
/
<-/
我有幾個關于這個問題的問題.
I have a few questions about this problem.
注意:服務器端在 Perl 中作為 CGI 腳本完成,我更希望看到(也)解決方案,而不使用像 jQuery 這樣的 JavaScript 庫/框架.
Note: server side is done as CGI script in Perl, and I would prefer to see (also) solution without using JavaScript library / framework like jQuery.
AJAX 應用服務器端使用的命令輸出是基于行的.每組線,以一種定義的線開始,以另一種線結束,由獨立且不可更改的數據組成.我應該只是將來自命令的響應流式傳輸為text/plain"并在客戶端用 JavaScript 進行處理,還是應該在服務器上預處理數據,并使用application/json"mimetype 將整個數據塊作為 JSON 發送?
The output of command used by server side of AJAX app is line based. Each group of lines, beginning with one defined kind of line, and ending with other kind of line, consist of independend and unchangeable data. Should I just stream response from a command as 'text/plain' and do processing in JavaScript on client side, or should I pre-process data on server, and send whole chunks of data as JSON using 'application/json' mimetype?
可能會發生服務器一次發送的大量數據之后很快就會有另一塊數據的情況.如何處理 onreadystatechange
處理程序被調用而先前的調用沒有完成工作的情況?我應該使用全局變量作為信號量,還是將狀態變量作為處理程序參數傳遞(好吧,使用 xhr.onreadystatechange = function() { handleRequest(xhr, state) }
)?
It might happen that large chunk of data send at once by server is followed soon by another chunk of data. How to deal with situation when onreadystatechange
handler is invoked while previous invocation didn't finished work? Should I use global variable as semaphore, or pass state variable as handler parameter (well, use xhr.onreadystatechange = function() { handleRequest(xhr, state) }
)?
我應該使用text/plain"還是application/json",或者可能是multipart/x0mixed-replace"?注意:這個應用程序應該可以在(幾乎)任何瀏覽器中運行.
Should I use 'text/plain' or 'application/json', or perhaps 'multipart/x0mixed-replace' for this? Note: this app should work in (alomst) any browser.
如何處理僅在收到完整響應后才調用 onReadyStateChange 的網絡瀏覽器(JavaScript 引擎)(所以我看不到 xhr.readyState == 3
即部分響應不止一次)?好吧,除了使用一些 JavaScript 框架.
How to deal with web browser (JavaScript engines) which invoke onReadyStateChange only after receiving complete response (so I don't see xhr.readyState == 3
i.e. partial response more than once)? Well, beside using some JavaScript framework.
如何處理不完整的響應(在這種情況下意味著不完整的行).
How to deal with incomplete responses (which in this situation mean incomplete lines).
我應該發送響應結束標記,還是依靠計數器來檢查我們是否收到了所有數據,或者我可以簡單地依靠檢測 xhr.readyState == 4
?
Should I send end of response marker, or rely on counter to check if we received all data, or can I simply rely on detecting xhr.readyState == 4
?
即使是部分回應也會有所幫助.
Even partial response would be helpful.
推薦答案
我認為 Comet 是您的解決方案所需的一部分.您還可以(如果我沒記錯的話)簽出 Bayeux Protocol,它是由 Dojo 基金會實施.整個事情還是很新的(盡管其中一些可能在第一個 HTML5 實現中是可能的).
I think Comet is part of what you need for your solution. You can additionally (if I got that right) checkout the Bayeux Protocol which was implemented by the Dojo Foundation. The whole thing is still very new (though some of it might be possible with the first HTML5 implementations).
除此之外,您可能還必須實施輪詢方法.另一個問題是,客戶端 JavaScript 解釋器可以處理多少數據.您是否有可能以某種方式分頁"您的數據,這樣您就不會遇到請求處理仍在處理而另一個響應已經到來的問題?
Besides that you would probably have to implement the polling approach. The other question is, how much data the client side JavaScript interpreter can handle. Is there any possibility for you to somehow "page" your data so that you won't have the problem of request handling still processing while aother response comes in already?
這篇關于在 AJAX 中處理增量服務器響應(在 JavaScript 中)的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!