Flash XMLSocket 通訊問題總結

來源:互聯網
上載者:User
 原文:http://blog.csdn.net/SCUM/archive/2008/10/21/3118175.aspx

1、前言
  本文以標準兩層 C/S 架構為例,對 XMLSocket 通訊編程作一沉痛總結。
  從開始到調試正常耗掉了我幾乎一周的時間,故為沉痛!尚東!!真是太尚東了!!!

 

  為方便描述,把 Flash Player 稱作用戶端(Client),包括獨立的 Player 和嵌入瀏覽器的 Player。

 

2、用途
  XMLSocket 類提供以 TCP/IP 方式進行程式間通訊的功能。

3、開發基本流程
  流程無所謂,先做服務端也好,先做用戶端也罷,都不可能把一邊做完再做另一邊,總之是要同步進行,除非服務端已經存在。

 

4、用戶端開發
  XMLSocket 類使用比較簡單,基本上就是幾個步驟:

 

  1) 建立 XMLSocket 類的執行個體。
  2) 寫好需要響應的事件代碼,事件很少,如下:
    onConnect: Socket 成功串連後觸發,傳入一個參數,指定串連狀態
    onClose: 伺服器端斷開 Socket 後觸發
    onData: 收到服務端資料,或傳輸錯誤時觸發,傳入一個參數,為 undefined 時表示傳輸錯誤,否則為收到的資料
    onXML: 收到服務端 XML 內容,或傳輸錯誤時觸發,參數同 onData

    典型的程式碼片段如下:
    ...
    var g_Socket = new XMLSocket();
    g_Socket.onConnect = ge_OnConnect;
    g_Socket.onClose = ge_OnDisconnect;
    g_Socket.onData = ge_OnData;
    ...



  3) 通過調用 connect( 服務端地址或IP, 服務連接埠 ) 方法發起串連請求。
  4) 串連若成功,資料的收發處理就由自己決定了。

 

5、服務端開發
  服務端根據情況可選各種語言開發,如 Java/C++/C#,只要能處理 Socket 的就行。
  個人感覺,開發前期可用 C++/單線程,輸出和調試都方便,等通訊層穩定後,可考慮用 Java 實現管理邏輯,線上程安全、記憶體回收、鎖等方面,Java 都比 C++ 來得方便。

 

  根據應用的不同,服務端的具體實現千變萬化,但基本的工作原理和內容是類似的:
  1) 初始化內部資料
  2) 開始監聽連接埠
  3) 處理串連請求
  4) 管理會話(Session)
  5) 管理線程
  6) 收集和分發資料
  7) 實現商務邏輯
  再展開來還有網路連接池、資料連線池、線程池、互動鎖等。

 

6、沙箱和安全性原則問題
  此問題發生在串連時,準確地說是串連前,分別兩種情況:

 

  6.1.1、本地播放
    本地播放時,預設情況下 Flash Player 將不允許 swf 訪問任何網路。
    訪問 http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html,將 swf 加入到許可列表,即可釋放保留。

 

  6.1.2、WEB 發布
    發布在 WEB 上的 swf, 將可能面臨跨域的問題。

    Flash 中的通訊方式有兩種:
    1) HTTP 方式:如 URLLoader 等用於載入遠程 swf、檔案、映像、音視頻流。
    2) Socket 主要:如 XMLSocket,用於與遠程服務端建立長效串連。

 

    Flash Player 6 以上版本引入了安全性原則檔案,在進行正式的通訊前,會檢查目標位置是否存在合法的安全性原則,以防止不同域內的應用無限制任意互訪。

 

    HTTP 方式下,Flash Player 會檢查目標域根目錄下是否存在 crossdomain.xml,如果有,則擷取並分析其內容(內容後述)以確定是否允許繼續訪問。

    Socket 方式下,Flash Player 擷取安全性原則稍微複雜些,從 9.0.115.0 版起,標準步驟如下(以下描述以 IE 為標準,例外情況後述):
    1) 首先向目標主機 843 連接埠發起串連,並發送一個字串,內容為 "<policy-file-request/>",並等待返回安全性原則檔案並分析。
    2) 若 1) 失敗,則檢查 AS 代碼中是否使用了 Security.loadPolicyFile( "xmlsocket://主機:連接埠" ) 方法載入安全性原則檔案,若有,則擷取並分析。
    3) 若 2) 失敗,則向 AS 代碼中即將串連的 "目標主機:連接埠" 發起請求,過程同 1)。
    4) 若成功獲得安全性原則檔案並經分析認為允許建立串連,則繼續執行 Connect() 方法,此時方真正嘗試建立與目標主機的串連。

 

  6.1.3、解決方案
    瞭解了上面說到的問題,解決方案便呼之欲出了,HTTP 串連方式不用再說,只說說 Socket 方式。
    1) 在服務端寫一個程式,監聽 843 連接埠,當收到 "<policy-file-request/>" 時將恰當的策略內容(crossdomain.xml)發送回用戶端。
    2) 在 AS 中通過 loadPolicyFile() 載入策略檔案,此處需注意使用 xmlsocket:// 而不是 http://。
    3) 在標準服務連接埠中,檢測到 "<policy-file-request/>" 時,返回策略內容。

 

  6.1.4、例外情況及測試結果
    經測試發現,在 IE, Opera 中,Flash Player 會嚴格按上述步驟檢查安全性原則。
    在 FireFox, Chrome 中發起串連時,Flash Player 並不會向服務端發送 "<policy-file-request/>",而是直接連接成功。這應該是 Flash Player 不同實現版本的原因。

 

7、資料轉送中的問題
  在 XMLSocket 資料轉送中,需要注意以下細節,否則會出來些莫名其妙的問題。

 

  7.1、結束符號
    XMLSocket 接收到服務端下發的資料時,將連續放於接收緩衝區,直到接收到 "/0" 位元組(位元組內容為 ASCII 值 0),才認為接收完成,並調用相應的 onData 或 onXML 事件。
    服務端若用 Java 編寫,並使用標準的 String 類族,則在發送資料結尾應手動加上 "/0"。
    若用 C++ 編寫,由於 C++ 中標準字串類型便是以位元組 0 作結束標記,故不必再加 "/0"。
    * C++ 中需注意另一個問題,若自行進行了字串處理,在決定字串長度時,標準的 strlen 及 String.Length() 等返回的均是實際有效字元個數,最終向網路發送時,總長度應加 1 位元組,以容納結尾的位元組 0。
    * 此問題在發送安全性原則內容時同樣存在,故需重視。

 

  7.2、中文問題
    預設情況下,不管從哪一端發向另一端的資料,若包含了中文字元,都會產生亂碼的現象,解決方案有二:
    1) 在 AS 中加入 "System.useCodepage = true;" 強制使用本地代碼集,此法最方便,但是在跨語種平台上仍會出現亂碼。
    2) 在代碼中自行編寫轉碼函數,此法複雜些,但通用性強。具體轉碼演算法網上很多,主要是 C++ 服務端需要,Java 中使用 JDK 類轉換為 UTF-8 即可。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.