如何同步actionscript中的方法?

发布于 2024-09-30 08:17:17 字数 2064 浏览 2 评论 0原文

问题是我怎样才能阻止一个方法被调用两次,例如第一次调用尚未“完成”,因为它的处理程序正在等待 url 加载?

情况是这样的:

  1. 我编写了一个 flash 客户端,它使用二进制加密协议与 java 服务器交互(我希望不必重新发明整个客户端/服务器对象通信堆栈,但我必须加密数据这样一来,如果使用 SSL,诸如篡改数据和 charles proxy 之类的简单工具就无法获取它们)。
  2. API 将自身作为动作脚本 swf 文件呈现给 flas,并且 API 本身是一个单例。
  3. 该 api 公开了一些简单的方法,包括:
    1. 登录()
    2. 获取余额()
    3. 开始游戏
    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. 我可以做一些诸如同步通信之类的事情。这会有效地阻止,但这比中断数据传输要好。理论上来说,Flash客户端不应该连续两次调用同一个api函数,但我却会发生这种情况。
  3. 我实现了一个消息队列。但是,这还需要围绕推送和弹出方法进行同步,我找不到如何做到这一点。

选项 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 完整事件处理程序,该处理程序还调用 api getBalance() 函数(即 flash多线程)。

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 that 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).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

天气好吗我好吗 2024-10-07 08:17:17

首先,除了网络 API 之外,Flash 不是多线程的。所有 ActionScript 都在同一个线程中运行。

您可以相当轻松地创建一个类似信号量的系统,其中每次通信调用都传递一个“键”以及您已经指定的参数。该“key”只是一个字符串,表示您正在执行的调用类型(getBalance、登录等)。 “键”将是通用对象(对象或字典)中的属性,并将引用数组(如果不存在则必须创建它)。

如果数组为空,则调用将正常进行。如果没有,则有关调用的信息将被放入一个对象中并推入数组中。然后,您的完整处理程序只需在完成调用后检查队列中是否有更多请求,如果有,则将其中一个请求出列并运行该请求。

关于这个系统的一件事是,它仍然允许不同类型的请求并行发生 - 但每个请求都必须有一个新的 URLLoader(只要在每个请求完成后清理它,这是完全合理的) 。

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文