IE6的連接數限制問題
先描述一下問題:有一個管理Job的UI,選中一些Job可以Run,每次只能啟動一個。還有一個UI通過Timer定時發Ajax請求服務端,查詢并顯示Job的運行狀況(進度)。
奇怪的問題出現了:
1)在FireFox和IE8運行正常(貌似正常,稍后再解釋)。其他瀏覽器未測試。
2)IE6,7及更早版本,Timer無法檢測到多于1個的Job運行。
先檢查了一遍代碼,Timer的控制沒有問題。不行就使用Fiddler吧。剛好是IE的問題。
觀察HTTP發現一個現象,運行Job的HTTP似乎沒有成功,因為Body是-1,之后是每隔一秒的Timer發起的HTTP。如果再啟動一個Job,發現Timer停止了!!
等待第一個Job運行成功之后,Timer又恢復了(重新發送Ajax請求)!!
似乎是運行Job的請求阻塞了(實際上該請求長時間沒有返回,因為運行Job需要幾分鐘甚至更多時間)。
為啥不使用DWR3.0的Push技術?后來跟同事討論明白,這不過是把Timer從客戶端轉移到了服務端。
記起來了,俺好像讀DWR源代碼的時候(當時對如何實現推非常感興趣),見過一段代碼分析Browser的類型和連接數,有的情況還拋出了異常。
明白了,肯定是IE6有連接數限制問題,后來得知,默認情況下,它不支持同時超過2個連接。哈哈。這就對了。
RunJob占用了一個(幾分鐘不等),
Timer占用了一個(很短暫)。
剛好2個。
- public class BrowserDetect
- {
- /**
- * How many connections can this browser open simultaneously?
- * @param request The request so we can get at the user-agent header
- * @return The number of connections that we think this browser can take
- */
- public static int getConnectionLimit(HttpServletRequest request)
- {
- if (atLeast(request, UserAgent.IE, 8))
- {
- return 6;
- }
- if (atLeast(request, UserAgent.Firefox, 3))
- {
- return 6;
- }
- else if (atLeast(request, UserAgent.AppleWebKit, 8))
- {
- return 4;
- }
- else if (atLeast(request, UserAgent.Opera, 9))
- {
- return 4;
- }
- else
- {
- return 2;
- }
- }
- //....
- }
接下來就是查資料做試驗,驗證該問題是否正確。通過在注冊表設置Internet Settings參數,實現了更多連接。例如10個。
但是Job可能很多,不可能無限制增加連接數,所以RunJob不應長期占用連接,它應該把Job插入隊列并立即返回。
至此問題的源頭終于找到了,Fiddler又幫了大忙。
讀源代碼是了解技術運作細節的最好方法,此外還能學到好的編程習慣。
-----------------------------------------------------
Silence, the way to avoid many problems;
Smile, the way to solve many problems;