2010-10-29 32 views
0

問題是我怎麼能停止一個方法被調用兩次,其中第一個調用沒有「完成」,因爲它的處理程序正在等待一個url加載例如?如何同步actionscript中的方法?

這裏的情況是:

  1. 我寫了一個Flash客戶端與使用二進制加密協議的Java服務器接口(我希望不會有重新發明了整個客戶端/服務器對象通信堆棧,但我必須以這樣一種方式加密數據,即使用簡單工具(如篡改數據和查爾斯代理)如果使用SSL,則無法將其加密)。
  2. API將自身呈現爲flas作爲actionscript swf文件,並且API本身是單例。
  3. 的API暴露了一些簡單的方法,包括:
    1. 登錄()
    2. 爲getBalance()
    3. startGame()
    4. 殘局()
  4. 每種方法都會打電話給我HttpCommunicator類。

HttpCommunicator.as(錯誤處理和東西刪除):

public class HttpCommunicator { 
    private var _externalHalder:function; 
    public function communicate(data:String, externalHandler:APIHandler):void {  
     // do encryption 
     // add message numbers etc to data. 
     this._externalHalder = externalHandler; 
     request.data = encrypt(addMessageNumers(data))); 
     loader.addEventListener(Event.COMPLETE, handleComplete); 
     loader.load(request); 
    } 

    private function handleComplete(event:Event):void { 
     var loader:URLLoader = URLLoader(event.target); 
      String data = decrypt(loader.data); 
      // check message numbers match etc. 
    _externalHandler(data); 
    } 

的問題,這是我不能保護它HttpCommunicator對象被調用之前,首先兩次已經處理完整的情況下,除非:

  1. 我每創建一個新的HttpCommunicator對象都要發送消息。我也想避免每次都創建一個URLLoader,但這不是我的代碼,因此知道它的行爲會更困難)。
  2. 我可以做類似syncronize通信。這會有效地阻止,但這比阻止數據傳輸更好。理論上,Flash客戶端不應該連續調用兩次相同的api函數,但我會發生。
  3. 我實現了一個消息隊列。然而,這也需要圍繞push和pop方法進行syncronization,我無法找到該方法。

將選項1.即使工作?如果我有一個方法,一個單說爲getBalance,併爲getBalance方法有:

// class is instantiated through a factory as a singleton 
public class API{ 
var balanceCommunicator:HttpCommunicator = new HttpCommunicator(); // create one for all future calls. 
public funciton getBalance(playerId:uint, hander:Fuction):Number { 
    balanceCommunicator.communicate(...); // this doesnt block 
    // do other stuff 
} 

將在第二呼叫痛擊第一電話傳播者變量?即它會像靜態一樣行爲,因爲只有API對象的一個​​副本?

如果說在GUI上有一個按鈕「更新餘額」,並且用戶不斷點擊它,同時說一個URLLoader完成事件hander被調用,同時也可以使apis getBalance()函數(即Flash是多線程的)。

回答

1

首先,除了網絡API之外,Flash不是多線程的。所有ActionScript都在同一個線程中運行。

你可以很容易地創建一個類似信號量的系統,其中每個調用通信都通過一個「key」以及你已經指定的參數。這個「key」只是一個表示你正在進行的調用類型的字符串(getBalance,login等)。 「鍵」將是通用對象(對象或字典)中的一個屬性,並且會引用一個數組(如果它不存在,則必須創建它)。

如果數組爲空,那麼調用將會像平常一樣發生。如果沒有,那麼有關該調用的信息將被放入一個對象中並被推入該數組中。然後,您的完整處理程序必須在完成調用後檢查隊列中是否有更多請求,如果是,請將它們中的一個出隊並運行該請求。

有關此係統的一件事情是,它仍然允許不同類型的請求並行發生 - 但是每個請求必須有一個新的URLLoader(這是非常合理的,只要在每個請求之後清理它即可)請求完成)。