<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Tin's Blog

    You are coming a long way, baby~Thinking, feeling, memory...

      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      128 隨筆 :: 0 文章 :: 221 評(píng)論 :: 0 Trackbacks

    1、引子

    引出本次討論的原因是dojo.io.IframeIO的問(wèn)題。在一個(gè)比較大的Javascript應(yīng)用中使用了dojo,dojo.io是dojo實(shí)現(xiàn)的非常好的一個(gè)地方,因?yàn)閐ojo.io用一個(gè)通用的接口封裝了XmlHttp、Iframe、ScriptSrc這幾種主流方式(Facade模式),是處理Ajax應(yīng)用IO的很好選擇。但是項(xiàng)目實(shí)際部署以后發(fā)現(xiàn)經(jīng)常出現(xiàn)操作無(wú)響應(yīng)的情況,經(jīng)過(guò)反復(fù)排查發(fā)現(xiàn)是使用的dojo.io.IframeIO的排隊(duì)沒(méi)有超時(shí)造成的。
    那么我們就要尋找問(wèn)題再哪里呢?

    2、問(wèn)題

    首先我們看到了dojo.io的bind方法中支持通用的timeout和timeoutSeconds參數(shù),這兩個(gè)參數(shù)從語(yǔ)意上看是為了給你的IO增加超時(shí)機(jī)制。當(dāng)初Ajaxian上有一篇介紹實(shí)際部署的Ajax項(xiàng)目需要注意的穩(wěn)定性問(wèn)題,其中比較重要的一條就是要給你的通訊排隊(duì)增加超時(shí),而dojo.io的這種設(shè)計(jì)正體現(xiàn)了這種觀點(diǎn)。那么我們還是首先分析一下為什么要排隊(duì)和為什么要超時(shí)機(jī)制。
    io通訊分同步和異步兩種方式,同步即需要阻塞等待,異步即無(wú)阻塞等待(異步回調(diào))。我們?cè)谑褂肵ML Http的時(shí)候可以選擇asynchronous為true和false,大家都知道它們就是是否同步。使用的地方大家都很熟悉了,比如兩個(gè)function有關(guān),它們的調(diào)用需要保證嚴(yán)格順序,那么就應(yīng)該同步通訊,前一個(gè)完了再調(diào)后一個(gè)。反之如果幾個(gè)function之間無(wú)關(guān),那么就可以異步通訊,減少用戶(hù)瀏覽器的阻塞和等待。
    OK,這種模型很清楚和簡(jiǎn)單。可是,實(shí)際上就XMLHttp而言,我們一般盡量不使用asynchronous=false,因?yàn)檫@樣瀏覽器會(huì)在傳輸?shù)臅r(shí)候失去對(duì)用戶(hù)的響應(yīng),用戶(hù)感覺(jué)比較差。對(duì)于需要嚴(yán)格順序的通訊我們使用另外一種方式,那就是回調(diào)的時(shí)候再調(diào)用下面一個(gè)函數(shù),這樣也可以保持嚴(yán)格順序,形成調(diào)用鏈。這種方式其實(shí)就是排隊(duì)模型 。在dojo中有一個(gè)queueBind方法,實(shí)際上就是包裝過(guò)的調(diào)用鏈。有了這些機(jī)制就可以滿(mǎn)足我們?nèi)粘5木幊棠P土耍坪鹾芡昝懒恕?br>可是,問(wèn)題在于并非所有io都可以提供排隊(duì)和非排隊(duì)的方式進(jìn)行通訊。比如iframe和ScriptSrc的方式實(shí)際上都是不支持非排隊(duì)的,因?yàn)檫@些通訊本質(zhì)上都是同步的(或者說(shuō)假異步),在只有一個(gè)Dom元素(iframe或者script元素)進(jìn)行通訊的時(shí)候其實(shí)所有的io都必須排隊(duì)。也就是說(shuō)可憐的iframe和scirptSrc方式都只有排隊(duì)……而不能不排隊(duì)……。這似乎也沒(méi)什么問(wèn)題,但是問(wèn)題來(lái)了……
    HTTP通訊并非可靠的通訊,它們都是最大努力的傳輸方式,也就是說(shuō)丟包是不可避免的,在發(fā)生丟包的時(shí)候如果恰巧你的通訊進(jìn)行了排隊(duì)而此時(shí)又沒(méi)有超時(shí)……那么你慘了,就出現(xiàn)了北京早晚場(chǎng)出現(xiàn)的堵車(chē)現(xiàn)象,往往僅僅是一輛輛車(chē)刮蹭了,后面的車(chē)就永久的成為了化石,多么的悲壯呀。
    所以,排隊(duì)的超時(shí)就非常重要了!一次通訊一定要有超時(shí)時(shí)間,這樣在阻塞時(shí)可以把阻塞消除。
    dojo在BrowserIO(XMLHttp)和ScriptSrcIO里面實(shí)現(xiàn)了超時(shí)機(jī)制,但是在IframeIO中沒(méi)有提供,這可能是個(gè)歷史遺留。
    而引子中所說(shuō)的問(wèn)題正來(lái)自這個(gè)不公平的待遇,iFrame的bind實(shí)際上就是queueBind(因?yàn)閐ojo的iFrameIO只用了一個(gè)iFrame),而又沒(méi)有超時(shí)機(jī)制……,然后應(yīng)用部署在實(shí)際網(wǎng)絡(luò)條件后就有很多用戶(hù)遇到了操作無(wú)響應(yīng)的問(wèn)題。

    3、解決

    找到問(wèn)題并理清思路離解決就非常近了。
    dojo的BrowserIO(XMLHttp)和ScriptSrcIO都使用了一種類(lèi)似onFlight的方式檢查超時(shí)。就是紀(jì)錄通訊開(kāi)始時(shí)間,然后傳輸時(shí)開(kāi)始輪訓(xùn)檢查是否超時(shí)。不直接用setTimeout檢查通訊超時(shí)是因?yàn)槿绻卸鄠€(gè)ScriptSrc或者XMLHttp通訊的時(shí)候可以防止互相沖突。
    我們也可以比較簡(jiǎn)單的向IframeIO中添加添加這樣的功能:
    OK,這里我偷懶了……。因?yàn)槲覀兊捻?xiàng)目只有一個(gè)iFrame作io,所以我們沒(méi)有使用onFlight方式,使用了setTimeout直接檢查的方式。大家先笑納,待簡(jiǎn)單修正把IframeIO也修改為onFlight的方式(然后提交dojo?)。
    如此看有點(diǎn)虎頭蛇尾,實(shí)際上就是這樣,問(wèn)題很大解決方法很小。我們經(jīng)常遇到的就是這樣的問(wèn)題。

    4、尾聲

    最后其實(shí)還是要回到j(luò)avascript應(yīng)用中的io問(wèn)題上來(lái)。這里我還要簡(jiǎn)單寫(xiě)一下我們常用到的io方式,我身邊還有很多同事不了解所以然。
    XML Http是這幾個(gè)io中最好的一個(gè),因?yàn)樗且粋€(gè)完整的IO實(shí)現(xiàn),有狀態(tài)回調(diào)機(jī)制,有abort等處理方法,但是相對(duì)來(lái)說(shuō)有幾個(gè)限制:瀏覽器支持、文件上傳、跨域。
    瀏覽器支持現(xiàn)在倒不算個(gè)問(wèn)題,Ajax應(yīng)用普遍是IE 5.5+、FF 1.0+、Opera 8+這樣子,它們都支持XMLHttp了。文件上傳用XMLHttp也比較難解決,雖然可以用客戶(hù)端切分的方法,但是用的人實(shí)際上很少(在這點(diǎn)上技術(shù)復(fù)雜性超過(guò)了iframe很多)。
    XMLHttp最大的限制是跨域,很?chē)?yán)格,甚至不能跨子域,這給我們的通訊帶來(lái)了巨大的限制。因?yàn)楹芏鄷r(shí)候我們要使用proxy或者負(fù)載均衡的分布式來(lái)解決這個(gè)問(wèn)題,這就增加了部署復(fù)雜性。
    相對(duì)來(lái)說(shuō)iframe則放松了這樣的限制,你可以跨子域(比如www.abc.com和ajax.abc.com和cde.xxx.abc.com),我們可以在文檔里面通過(guò)domain="abc.com"來(lái)強(qiáng)制用根域做js執(zhí)行的域。但是這種做法也有麻煩,比如Firefox 1.0.x的一些版本如果domain="abc.com"執(zhí)行以后會(huì)造成XMLHttp通訊失敗,此時(shí)我們就沒(méi)法在用iframe的同時(shí)用XMLHttp了。
    iframe的另外一種好處是它比較容易解決文件上傳的問(wèn)題,只要對(duì)form指向一下target為iframe就可以無(wú)刷新上傳了,這幾乎是最簡(jiǎn)單的方案。
    但是iframe的限制還是滿(mǎn)多的,它比較復(fù)雜,在Tencent這樣的倒霉瀏覽器中設(shè)置了所有鏈接都在新窗口中打開(kāi)后會(huì)讓?xiě)?yīng)用很難看并不可用,它沒(méi)有完全的解決跨域問(wèn)題等等。
    為了解決iframe的不能跨根域的問(wèn)題,引入了ScriptSrc的方式。就是指<script src="xxx.js" id="scriptIo"></script>,然后動(dòng)態(tài)修改src這樣的方式。為了瀏覽器兼容,此種方式下需要?jiǎng)討B(tài)的創(chuàng)建script節(jié)點(diǎn),然后再刪除,否則內(nèi)容不會(huì)載入(非IE的情況)。所以技術(shù)復(fù)雜度相對(duì)也比較高。但是這種方式可以完全解決跨域問(wèn)題,你可以將src指向任何地方!
    那么缺點(diǎn)是ScriptSrc在動(dòng)態(tài)刪節(jié)點(diǎn)的時(shí)候潛在存在內(nèi)存泄露,據(jù)稱(chēng)不太好解決。而更大的問(wèn)題是如果傳輸json的話,必須用var json = {property:value};這樣的形勢(shì),對(duì)json有了污染,不太好。
    所以,對(duì)于io的方案主要來(lái)說(shuō)幾個(gè)點(diǎn):
    a、跨域:ScriptSrc完全跨域,iFrame跨子域,XmlHttp不跨域。
    b、文件:傳文件iframe比較簡(jiǎn)單,ScriptSrc和XmlHttp都需要客戶(hù)端切分get上去,比較麻煩。
    c、生命周期控制:XmlHttp比較完善,而iFrame可以模擬但是不完全,ScriptSrc則更難。

    需要代碼請(qǐng)去JavaEye下載:D
    http://www.javaeye.com/topic/82169

    That's all。本來(lái)想No fluff just staff的寫(xiě)這篇東西,但是無(wú)奈嘴碎寫(xiě)的優(yōu)點(diǎn)亂,請(qǐng)大家見(jiàn)諒。關(guān)于本問(wèn)題的解決希望大家多提意見(jiàn),互相交流。
    posted on 2007-05-23 11:44 Tin 閱讀(1081) 評(píng)論(4)  編輯  收藏

    評(píng)論

    # re: 為dojo.io.IframeIO添加超時(shí),同時(shí)簡(jiǎn)析Ajax的IO方式 2007-06-14 23:05 whyork@21cn.com
    很好的文章!  回復(fù)  更多評(píng)論
      

    # re: 為dojo.io.IframeIO添加超時(shí),同時(shí)簡(jiǎn)析Ajax的IO方式 2007-11-05 19:37 juyizhou
    我找不到dojo的源碼-_-#

    Tin能給個(gè)鏈接嗎?  回復(fù)  更多評(píng)論
      

    # re: 為dojo.io.IframeIO添加超時(shí),同時(shí)簡(jiǎn)析Ajax的IO方式 2007-11-05 20:22 juyizhou
    I got it.

    Tin有經(jīng)典些的java實(shí)現(xiàn)的超時(shí)機(jī)制的實(shí)現(xiàn)嗎?謝謝!  回復(fù)  更多評(píng)論
      

    # re: 為dojo.io.IframeIO添加超時(shí),同時(shí)簡(jiǎn)析Ajax的IO方式[未登錄](méi) 2007-11-05 22:29 Tin
    java實(shí)現(xiàn)超時(shí)檢測(cè)除了使用某些對(duì)象內(nèi)置的功能,那么只有setTimeout和siteInterval了,沒(méi)啥好辦法。  回復(fù)  更多評(píng)論
      


    只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲高清视频一视频二视频三| 亚洲AV无码不卡在线播放| 国产免费A∨在线播放| 亚洲av无码一区二区三区乱子伦 | 久久久国产精品亚洲一区| 特级做A爰片毛片免费69| 深夜特黄a级毛片免费播放| 亚洲AV无码精品无码麻豆| 无人在线观看完整免费版视频| 四虎影视永久在线精品免费| 亚洲黄色免费网站| 国产成人免费ā片在线观看| 久久久久免费看黄a级试看| 精品亚洲av无码一区二区柚蜜| 亚洲avav天堂av在线不卡| 免费国产在线观看老王影院| 无码国产精品一区二区免费3p | 亚洲av之男人的天堂网站| 免费人成视频在线| 女同免费毛片在线播放| 亚洲另类无码专区丝袜| 国产福利在线免费| 国产亚洲美女精品久久久久| 亚洲人成依人成综合网| 亚洲AⅤ优女AV综合久久久| 亚洲精品视频在线免费| 国产区在线免费观看| 亚洲Av永久无码精品一区二区| 亚洲人成依人成综合网| 国产亚洲精午夜久久久久久| 国产精品美女自在线观看免费 | 美女黄网站人色视频免费国产| 美女在线视频观看影院免费天天看| 亚洲国产无线乱码在线观看| 亚洲美女视频免费| 亚洲国产另类久久久精品小说| 国产成人免费片在线观看| 91在线视频免费91| 日本高清在线免费| 99在线在线视频免费视频观看| eeuss免费天堂影院|