如何防止 RemoteObject 将 AMF 消息批量处理在一起?

发布于 2024-08-17 05:28:11 字数 507 浏览 6 评论 0原文

我正在使用 Google AppEngine 与 PyAMF 结合来提供 RemoteObject 支持。在我的 Flex 代码中,我同时调用多个 RemoteObject 方法,这往往会将 AMF 消息批处理为单个 HTTP 请求。

大多数时候这很好,但 AppEngine 对每个请求应用一些严格的限制(在这种情况下,我遇到了 DeadlineExceededError - 最多 30 秒)。许多服务方法预计需要 10 秒以上,如果这些方法由 RemoteObject 批处理为 1 个 HTTP .. 您就会看到这是怎么回事。

现在您可以说重构您的服务调用,这也正在发生,但实际上并不是这里提出的问题。有没有办法防止 Flex RemoteObject 在这种情况下批量处理 AMF 请求?

我对这个主题进行了大量的谷歌搜索,并得出了一些结论。在我看来,我需要实现 mx.messaging.channels.AMFChannel 的自定义版本或类似性质的东西,这对于这样的功能来说似乎太核心了..

任何人都有任何指示/洞察力?

I am using Google AppEngine, in conjunction with PyAMF to provide RemoteObject support. In my Flex code I make several RemoteObject method calls at once which tends to batch the AMF Messages into a single HTTP request.

Most of the time this is fine but AppEngine applies some strict per request limits (in this case I am hitting a DeadlineExceededError - max 30 seconds). A number of service methods are expected to take upwards of 10 seconds and if these are batched by the RemoteObject into 1 HTTP .. you see where this is going.

Now you could say refactor your service calls and that is also going on but not really the question being asked here. Is there a way to prevent Flex RemoteObject from batching AMF requests for situations like this?

I have done a fair amount of Googling on the subject and come up with bupkis. It seems to me that I would need to implement a custom version of mx.messaging.channels.AMFChannel or something of that nature, which seems waay too hardcore for a feature like this ..

Anyone have any pointers/insight?

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

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

发布评论

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

评论(5

捶死心动 2024-08-24 05:28:11

查看并发属性远程对象。

Check out the concurrency property on RemoteObject.

浅听莫相离 2024-08-24 05:28:11

将 AMF 请求批处理为 HTTP 发生在 NetConnection 级别。因此,不幸的是,阻止 AMF 请求批处理的最佳方法是实现 mx.messaging.channels.AMFChannel。然而,这很容易做到,并且可能比排队请求并稍后调用它们更容易。

不要使用默认的 AMFChannel,而是使用以下方法:

package services
{
    import flash.events.AsyncErrorEvent;
    import flash.events.IOErrorEvent;
    import flash.events.NetStatusEvent;
    import flash.events.SecurityErrorEvent;
    import flash.net.NetConnection;

    import mx.messaging.MessageResponder;
    import mx.messaging.channels.AMFChannel;

    public class NonBatchingAMFChannel extends mx.messaging.channels.AMFChannel
    {
        public function NonBatchingAMFChannel(id:String = null, uri:String = null)
        {
            super(id, uri);
        }

        override protected function internalSend(msgResp:MessageResponder):void
        {
            // AMFChannel internalSend
            super.internalSend(msgResp);
            // Reset the net connection.
            _nc = new NetConnection();
            _nc.addEventListener(NetStatusEvent.NET_STATUS, statusHandler); 
            _nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); 
            _nc.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler); 
            _nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler); 
            _nc.connect(this.url);
        }
    }
}

神奇的事情是通过重写internalSend 方法来实现的。运行超级internalSend方法(它将消息响应程序排队)后,我们将重置NetConnection及其所有事件处理程序。这将为下一个远程处理消息准备好新的 NetConnection。

笔记:
需要注意的是,这是一个自定义的非批处理 AMFChannel,如果您想安全地发送 AMF 消息,您需要复制此类并扩展 mx.messaging.channels.SecureAMFChannel 类。

信用:
感谢尼克·乔伊斯(Nick Joyce)在另一个论坛上回答了他的问题。

The batching of AMF requests into HTTP happens at the NetConnection level. So unfortunately the best way to stop AMF requests from batching is to implement a custom version of the mx.messaging.channels.AMFChannel. However this is quite easy to do, and probably easier that queuing requests and calling them later.

Instead of using the default AMFChannel use the following instead:

package services
{
    import flash.events.AsyncErrorEvent;
    import flash.events.IOErrorEvent;
    import flash.events.NetStatusEvent;
    import flash.events.SecurityErrorEvent;
    import flash.net.NetConnection;

    import mx.messaging.MessageResponder;
    import mx.messaging.channels.AMFChannel;

    public class NonBatchingAMFChannel extends mx.messaging.channels.AMFChannel
    {
        public function NonBatchingAMFChannel(id:String = null, uri:String = null)
        {
            super(id, uri);
        }

        override protected function internalSend(msgResp:MessageResponder):void
        {
            // AMFChannel internalSend
            super.internalSend(msgResp);
            // Reset the net connection.
            _nc = new NetConnection();
            _nc.addEventListener(NetStatusEvent.NET_STATUS, statusHandler); 
            _nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); 
            _nc.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler); 
            _nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler); 
            _nc.connect(this.url);
        }
    }
}

The magic happens by overriding the internalSend method. After running the super internalSend method (which queues the message responder), we will reset the NetConnection and all of its event handlers. This gets a new NetConnection ready for the next remoting message.

Note:
It's important to note that this is a custom non batching AMFChannel, if you want send AMF messages securely you'll need to copy this class and extend the mx.messaging.channels.SecureAMFChannel class.

Credit:
Credit to Nick Joyce who answered his question here on a different forum.

杯别 2024-08-24 05:28:11

您可以创建一个连接池,并创建另一个触发连接的类。您的应用程序不建立连接,仅向池提供数据。

you can create a pool of connections, and create another another class that triggers the connections. Your application does not make the connections, only feeds the pool.

岁月苍老的讽刺 2024-08-24 05:28:11

好吧,一种方法显然是推出自己的不使用 NetConnection 的 AMFChannel...我还没有尝试过,所以我不知道它的效果如何。
http://blogs.adobe.com/pfarland/2008/06/using_amf_with_flashneturlload.html

Well, one way is apparently to roll your own AMFChannel that doesn't use NetConnection... I haven't tried it so I don't know how well it works.
http://blogs.adobe.com/pfarland/2008/06/using_amf_with_flashneturlload.html

我一直都在从未离去 2024-08-24 05:28:11

我认为 njoyce 喜欢做的就是阻止 AMF 批处理。这个即。对于多个小型调用很有用,但如果您有服务器密集型调用,则应阻止 AMF 批处理。为什么?

  • 一次 AMF 调用 =>服务器端的一个线程
  • 多个 AMF 调用 =>所有请求都通过多个线程处理

伪代码:

    private static var _collectionFillIndex:int;
    private static var _collectionsToFill:Array = [];

    public function doFillCollections():void {
        _collectionFillIndex = _collectionsToFill.length;
        Application.application.addEventListener( Event.ENTER_FRAME, onFrameEventHandler );
    }

    private function onFrameEventHandler( event:Event ):void {
        --_collectionFillIndex;
        if( _collectionFillIndex < 0 ) {
            Application.application.removeEventListener( Event.ENTER_FRAME, onFrameEventHandler );
            return;
        }
        _collectionsToFill[ _managerFillIndex ].fill();
    } 

I think what njoyce like to do is to prevent AMF batching. This ie. is good for multiple small calls but if you have very server-intensive calls you AMF batching should be prevented. Why?

  • one AMF call => one thread on server side
  • multiple AMF calls => all requests get handled through multiple threads

Pseudo Code:

    private static var _collectionFillIndex:int;
    private static var _collectionsToFill:Array = [];

    public function doFillCollections():void {
        _collectionFillIndex = _collectionsToFill.length;
        Application.application.addEventListener( Event.ENTER_FRAME, onFrameEventHandler );
    }

    private function onFrameEventHandler( event:Event ):void {
        --_collectionFillIndex;
        if( _collectionFillIndex < 0 ) {
            Application.application.removeEventListener( Event.ENTER_FRAME, onFrameEventHandler );
            return;
        }
        _collectionsToFill[ _managerFillIndex ].fill();
    } 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文