• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            loop_in_codes

            低調(diào)做技術(shù)__歡迎移步我的獨(dú)立博客 codemaro.com 微博 kevinlynx

            使用ActionScript開(kāi)發(fā)Ice Web客戶(hù)端

            我們目前的項(xiàng)目服務(wù)器端使用了Ice來(lái)構(gòu)建。Ice有一套自己的網(wǎng)絡(luò)協(xié)議,客戶(hù)端和服務(wù)器端可以基于此協(xié)議來(lái)交互。由于Ice使用Slice這種中間語(yǔ)言來(lái)描述服務(wù)器和客戶(hù)端的交互接口,所以它可以做到極大限度地屏蔽網(wǎng)絡(luò)協(xié)議這個(gè)細(xì)節(jié)。也就是說(shuō),我們只要借助Ice和Slice,我們可以輕松地編寫(xiě)網(wǎng)絡(luò)程序。

            然后,我們的后端現(xiàn)在需要一個(gè)運(yùn)行在Web瀏覽器上的客戶(hù)端。要與Ice做交互,如果使用TCP協(xié)議的話,得保證是長(zhǎng)連接的。但HTTP是短連接的。而另一方面,我們還需要選擇一個(gè)Ice支持的和Web相關(guān)的語(yǔ)言來(lái)做這件事情。如果要在瀏覽器端直接與Ice服務(wù)建立連接,可供選擇的語(yǔ)言/平臺(tái)包括:

            • Flash
            • Silverlight

            因?yàn)槲抑坝胑rlang簡(jiǎn)單寫(xiě)了個(gè)Ice的客戶(hù)端庫(kù),所以我對(duì)Ice底層協(xié)議有一定了解,可以不一定使用Ice支持的語(yǔ)言,所以HTML5其實(shí)也是個(gè)選擇。此外,如果在瀏覽器端使用Applet,Java可能也是個(gè)選擇。

            其實(shí)幾個(gè)月前在這塊的技術(shù)選擇問(wèn)題上我就做過(guò)簡(jiǎn)單的研究,當(dāng)時(shí)確定的方案是使用Flash。但是,后來(lái)人員招聘上遇到了問(wèn)題,看起來(lái)要招一個(gè)會(huì)ActionScript和前端頁(yè)面技術(shù)的程序員來(lái)做我們這種項(xiàng)目,似乎大材小用,成本顯高了。

            那么,考慮到團(tuán)隊(duì)里有現(xiàn)成的Java程序員,而且看起來(lái)招一個(gè)會(huì)用Java寫(xiě)網(wǎng)站的程序員簡(jiǎn)單又便宜,似乎是排除技術(shù)原因的最好選擇。但是,如果不在瀏覽器端直接連接服務(wù)器來(lái)做交互,而是讓W(xué)eb服務(wù)器端來(lái)做中轉(zhuǎn)的話,會(huì)面臨不少問(wèn)題:

            • 瀏覽器端操作結(jié)果的獲取問(wèn)題,說(shuō)白了就是非實(shí)時(shí)了,得用Ajax等等技術(shù)去模擬實(shí)時(shí),代價(jià)就是不斷輪訓(xùn),也就是通常說(shuō)的poll
            • Web服務(wù)器端需要編寫(xiě)大量代碼:對(duì)用戶(hù)操作的映射,結(jié)果緩存等等

            如果能用Flash包裝與服務(wù)器交互的部分,而把UI相關(guān)的東西留給HTML/JS/CSS去做,那是不是可行一點(diǎn)?如果只是用ActionScript編寫(xiě)與服務(wù)器端的交互邏輯代碼,我就不需要花時(shí)間去系統(tǒng)學(xué)習(xí)ActionScript,甚至如何用Flash做界面,我甚至不用搞懂這些技術(shù)之間的關(guān)系。基本上看些Ice for ActionScript的例子代碼,就可以完成這件事情。

            以下記錄一些主要的過(guò)程/方法:

            ActionScript程序的開(kāi)發(fā)

            開(kāi)發(fā)一個(gè)嵌入到網(wǎng)頁(yè)中的FLASH,只需要Flex SDK。SDK里自帶了一些編譯器相關(guān)工具。我不打算使用IDE,因?yàn)榭雌饋?lái)IDE更復(fù)雜。簡(jiǎn)單的google之后,基本就可以構(gòu)建出一個(gè)Flash文件:

            • 構(gòu)建基本的程序需要一個(gè)mxml文件,這個(gè)文件里主要用來(lái)捕獲Flash在頁(yè)面上初始化完成這個(gè)事件,以初始化內(nèi)部邏輯
            • 編寫(xiě)ActionScript源碼,看起來(lái)其文件、類(lèi)的組織方式很像Java
            • 使用Flex SDK中的mxmlc程序來(lái)編譯,生成swf文件,例如:

              mxmlc myflexapp.mxml -library-path+=xxx.swc

            • 嵌入到網(wǎng)頁(yè)中,簡(jiǎn)單的做法可以借助swfobject.js這個(gè)庫(kù),嵌入的方式:

                 <script type="text/javascript" src="swfobject.js"></script>
                <script type="text/javascript">
                    var flashvars = {};
                    var params = {};
                  params.play = "true";
                    params.quality = "high";
                    params.bgcolor = "white";
                    params.allowscriptaccess = "always";
                    params.allowfullscreen = "true";
                    var attributes = {};
                    attributes.id = "asclient";
                    attributes.name = "asclient";
                    attributes.align = "middle";
                    swfobject.embedSWF("asclient.swf", "flashContent", "1", "1",
                        "0", "", 
                        flashvars, params, attributes);
                    swfobject.createCSS("#flashContent", "display:none;");
                </script>
            

            自然,頁(yè)面中需加入flashContent這個(gè)div:

                 <div id="flashContent">
                    <p>no flash</p>
                </div>
            

            我的mxml文件也很簡(jiǎn)單:

            <?xml version="1.0" encoding="utf-8"?>
            <s:Application 
                xmlns:fx="http://ns.adobe.com/mxml/2009" 
                xmlns:s="library://ns.adobe.com/flex/spark" 
                xmlns:mx="library://ns.adobe.com/flex/mx"
                applicationComplete="doApplicationComplete()" >
                <fx:Script>
                <![CDATA[
                   import ASClient.Coordinator;
                   import flash.external.ExternalInterface;
            
                   private var _coordinator:Coordinator;
            
                   public function doApplicationComplete():void
                   {
                        trace("doApplicationComplete");
                        _coordinator = new Coordinator();
                        _coordinator.reg_methods();
                        ExternalInterface.call("as_ready"); 
                   } 
                 ]]>
                </fx:Script>
            </s:Application>
            

            ActionScript日志

            我通過(guò)日志來(lái)調(diào)試ActionScript代碼。最簡(jiǎn)單的方式就是通過(guò)trace函數(shù)來(lái)輸出日志。要成功輸出日志包含以下步驟:

            • 給瀏覽器安裝調(diào)試版本的Flash Player
            • 日志是輸出到用戶(hù)目錄下的,并且需要手動(dòng)創(chuàng)建日志目錄(Administrator替換為用戶(hù)名):

                C:\Users\Administrator\AppData\Roaming\Macromedia\Flash Player\Logs
              
            • 用戶(hù)目錄下新建配置文件mm.cfg:

                AS3StaticProfile=0
                AS3Verbose=0
                TraceOutputFileEnable=1 
                TraceOutputBuffered=0
                ErrorReportingEnable=1  
                AS3Trace=0
              
            • 編譯DEBUG版本的Flash文件,可以修改flex sdk下的flex-config.xml文件,里面增加debug=true配置即可

            在開(kāi)發(fā)過(guò)程中需要注意瀏覽器緩存問(wèn)題,當(dāng)編譯出新的Flash文件后,瀏覽器即使頁(yè)面刷新也可能使用的是緩存里的Flash。當(dāng)然,最重要的,是通過(guò)瀏覽器來(lái)訪問(wèn)這個(gè)包含了Flash的網(wǎng)頁(yè),Web服務(wù)器隨意。

            Flash Policy文件

            在Flash的某個(gè)版本后,F(xiàn)lash中如果要向外建立socket連接,是首先要取得目標(biāo)主機(jī)返回的policy文件的。也就是在建立連接前,F(xiàn)lash底層會(huì)先向目標(biāo)主機(jī)詢(xún)問(wèn)得到一個(gè)描述訪問(wèn)權(quán)限的文件。

            簡(jiǎn)單來(lái)說(shuō),目標(biāo)主機(jī)需要在843端口上建立TCP監(jiān)聽(tīng),一旦有網(wǎng)絡(luò)連接,就發(fā)送以下內(nèi)容,內(nèi)容后需添加0x00用于標(biāo)示結(jié)束。(當(dāng)然,具體細(xì)節(jié)還挺多,自行g(shù)oogle)

            <cross-domain-policy>
                 <allow-access-from domain="*" to-ports="*" />
            </cross-domain-policy>
            

            最開(kāi)始我使用的是朋友給的現(xiàn)成的Policy服務(wù),雖然我寫(xiě)的Flash可以成功連接我的Ice服務(wù),但始終要等待2秒以上的時(shí)間。google Flash Policy相關(guān)內(nèi)容,可以發(fā)現(xiàn)確實(shí)存在一個(gè)延時(shí),但那是因?yàn)槟繕?biāo)主機(jī)沒(méi)有在843端口服務(wù)。后來(lái)我自己用erlang寫(xiě)了個(gè)Policy服務(wù),延時(shí)就沒(méi)有了。猜測(cè)可能是他的Policy服務(wù)沒(méi)有添加0x00作為結(jié)束導(dǎo)致。

            ActionScript與JavaScript的交互

            既然我使用ActionScript來(lái)包裝與服務(wù)器的交互,那么JavaScript就必然需要和ActionScript通信。這個(gè)通信過(guò)程也就是在JavaScript中調(diào)用ActionScript中的函數(shù),反過(guò)來(lái)亦然。這個(gè)過(guò)程很簡(jiǎn)單:

            在JavaScript中調(diào)用ActionScript函數(shù):

            首先是ActionScript需要注冊(cè)哪些函數(shù)可以被調(diào)用:

            ExternalInterface.addCallback("service_loadall", loadAll);
            

            通過(guò)ExternalInterface.addCallback注冊(cè)的函數(shù),其實(shí)是個(gè)closure,所以在類(lèi)中注冊(cè)自己的成員函數(shù)都可以(因?yàn)槌蓡T函數(shù)會(huì)使用this,形成了一個(gè)closure)。

            然后在JavaScript中調(diào)用:

                function asObject() {
                    // asclient是嵌入Flash時(shí)填入的name和(或?)id
                    return window.document.asclient;
                }
                var as = asObject();
                as.service_loadall();
            

            在ActionScript中調(diào)用JavaScript中調(diào)用則更簡(jiǎn)單,一句話:

            ExternalInterface.call("service_load_done", args);
            

            至于在兩者之間的函數(shù)參數(shù)傳遞,其類(lèi)型都可以自動(dòng)映射。但因?yàn)槲业膽?yīng)用里數(shù)據(jù)較為復(fù)雜,我就將數(shù)據(jù)轉(zhuǎn)換為JSON格式,在JavaScript這邊操作較為簡(jiǎn)單。

            頁(yè)面切換

            這里我們需要的Web前端頁(yè)面,更像是一個(gè)管理系統(tǒng),所以頁(yè)面切換是很有可能的。問(wèn)題在于,當(dāng)出現(xiàn)頁(yè)面跳轉(zhuǎn)時(shí),F(xiàn)lash對(duì)象會(huì)重新初始化,新的頁(yè)面無(wú)法使用前一個(gè)頁(yè)面建立好的網(wǎng)絡(luò)連接(或者能?)。為了解決這個(gè)問(wèn)題,服務(wù)器當(dāng)然可以設(shè)計(jì)一種重登錄機(jī)制,方便客戶(hù)端以一種特殊的方式進(jìn)入系統(tǒng),繞過(guò)正常的登錄環(huán)節(jié)。但是我們使用了Glacier2這個(gè)網(wǎng)關(guān),在這個(gè)網(wǎng)關(guān)上有針對(duì)連接的超時(shí)管理,這樣反復(fù)建立新的連接對(duì)資源太浪費(fèi)了。

            綜上,我想只能通過(guò)前端去規(guī)避這個(gè)問(wèn)題。例如,前端開(kāi)發(fā)人員依然可以分開(kāi)設(shè)計(jì)很多頁(yè)面,頁(yè)面里也可以使用正常的鏈接。我們編寫(xiě)一些JavaScript代碼,將頁(yè)面里的鏈接替換成對(duì)應(yīng)的JavaScript代碼,動(dòng)態(tài)載入新的頁(yè)面內(nèi)容,然后對(duì)頁(yè)面內(nèi)的部分內(nèi)容進(jìn)行替換,從而盡可能讓頁(yè)面設(shè)計(jì)人員編寫(xiě)正常的網(wǎng)頁(yè),同時(shí)也解決頁(yè)面切換問(wèn)題。

            這是個(gè)蹩腳的方法,但在我有限的前端知識(shí)體系下,似乎也只能這樣干了。

            posted on 2013-06-10 21:30 Kevin Lynx 閱讀(2150) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): web


            只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            久久久久久国产精品无码下载| 精品久久久久久无码不卡| 中文精品99久久国产| 99久久www免费人成精品| 久久99国内精品自在现线| 亚洲精品无码成人片久久| 国产偷久久久精品专区| 久久人人爽人人人人爽AV| 伊人色综合久久天天人守人婷| 久久久久综合国产欧美一区二区| 久久精品国产精品青草app| 久久精品国产福利国产秒| 日本福利片国产午夜久久| 91久久精品无码一区二区毛片| 国产一级做a爰片久久毛片| 国产精品久久影院| 婷婷综合久久狠狠色99h| 欧美精品一本久久男人的天堂| 91精品婷婷国产综合久久 | 青青草原综合久久| 色综合久久久久久久久五月| 久久久久久精品免费看SSS | 日韩中文久久| 99久久国产综合精品成人影院| www亚洲欲色成人久久精品| 久久久国产精华液| 欧美亚洲国产精品久久久久| 亚洲精品无码久久久影院相关影片 | 国产精品伦理久久久久久| 91秦先生久久久久久久| 色综合合久久天天给综看| 一本色道久久99一综合| 狠狠色婷婷久久一区二区三区 | 久久久无码精品亚洲日韩蜜臀浪潮| 久久强奷乱码老熟女| 一本久久a久久精品亚洲| 97久久精品人人做人人爽| 国内精品久久国产| 99久久国产综合精品成人影院| yy6080久久| 久久精品国产亚洲Aⅴ香蕉|