如何防止RemoteObject将AMF消息批处理?

时间:2010-01-10 16:25:43

标签: flex messaging remoteobject batching

我正在使用Google AppEngine与PyAMF一起提供RemoteObject支持。在我的Flex代码中,我立即进行了几次RemoteObject方法调用,这往往会将AMF消息批处理为单个HTTP请求。

大部分时间这都很好,但AppEngine对每个请求限制应用了一些严格的限制(在这种情况下,我遇到DeadlineExceededError - 最多30秒)。许多服务方法预计需要10秒以上,如果这些方法被RemoteObject批量分配到1个HTTP中,你会看到它的发展方向。

现在你可以说重构一下你的服务电话,这也正在进行但不是真正的问题。有没有办法阻止Flex RemoteObject在这种情况下批量处理AMF请求?

我已经在这个主题上做了相当多的谷歌搜索并提出了bupkis。在我看来,我需要实现mx.messaging.channels.AMFChannel的自定义版本或者那种性质的东西,对于像这样的功能来说这似乎太硬了......

任何人都有任何指示/见解?

5 个答案:

答案 0 :(得分:1)

查看RemoteObject上的concurrency property

答案 1 :(得分:1)

将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方法可以实现神奇。在运行super internalSend方法(对消息响应程序进行排队)之后,我们将重置NetConnection及其所有事件处理程序。这将为下一个远程处理消息准备好新的NetConnection。

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

信用: 感谢Nick Joyce,他在另一个论坛上回答了他的问题。

答案 2 :(得分:0)

您可以创建一个连接池,并创建另一个触发连接的类。您的应用程序不进行连接,只提供池。

答案 3 :(得分:0)

嗯,有一种方法显然是推出自己不使用NetConnection的AMFC通道......我没有尝试过,所以我不知道它有多好用。 http://blogs.adobe.com/pfarland/2008/06/using_amf_with_flashneturlload.html

答案 4 :(得分:0)

我认为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();
    }