开发者

how to synchronize methods in actionscript?

The question is how could I stop a method being called twice, where the first call has not "completed" because its handler is waiting for a url to load for example?

Here is the situation:

  1. I have written a flash client which interfaces with a java server using a binary encrypted protocol (I would love to not have had to re-invent the whole client/server object communcation stack, but I had to encrypt the data in such a way th开发者_Go百科at simple tools like tamper data and charles proxy could not pick them up if using SSL).
  2. The API presents itself to flas as an actionscript swf file, and the API itself is a singleton.
  3. the api exposes some simple methods, including:
    1. login()
    2. getBalance()
    3. startGame()
    4. endGame()
  4. Each method will call my HttpCommunicator class.

HttpCommunicator.as (with error handling and stuff removed):

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);
    }

The problem with this is I cant protect the same HttpCommunicator object from being called twice before the first has handled the complete event, unless:

  1. I create a new HttpCommunicator object every single time I want to send a message. I also want to avoid creating a URLLoader each time, but this is not my code so will be more problematic to know how it behaves).
  2. I can do something like syncronize on communicate. This would effectivly block, but this is better than currupting the data transmission. In theory, the Flash client should not call the same api function twice in a row, but I but it will happen.
  3. I implement a queue of messages. However, this also needs syncronization around the push and pop methods, which I cant find how to do.

Will option 1. even work? If I have a singleton with a method say getBalance, and the getBalance method has:

// 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
}

Will the second call trounce the first calls communicator variable? i.e. will it behave as if its static, as there is onlyone copy of the API object?

If say there was a button on the GUI which had "update balance", and the user kept clicking on it, at the same time as say a URLLoader complete event hander being called which also cals the apis getBalance() function (i.e. flash being multithreaded).


Well, first off, with the exception of the networking APIs, Flash is not multithreaded. All ActionScript runs in the same one thread.

You could fairly easily create a semaphore-like system where each call to communicate passed in a "key" as well as the arguments you already specified. That "key" would just be a string that represented the type of call you're doing (getBalance, login, etc). The "key" would be a property in a generic object (Object or Dictionary) and would reference an array (it would have to be created if it didn't exist).

If the array was empty then the call would happen as normal. If not then the information about the call would be placed into an object and pushed into the array. Your complete handler would then have to just check, after it finished a call, if there were more requests in the queue and if so dequeue one of them and run that request.

One thing about this system would be that it would still allow different types of requests to happen in parallel - but you would have to have a new URLLoader per request (which is perfectly reasonable as long as you clean it up after each request is done).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜