超时似乎约为10秒。可以修改吗?
答案 0 :(得分:1)
我没有看到内置的方法。 但是,它绝对可以自己实现。
只需创建一个表示您对NetConnection实例进行的每次调用的事务类。
此事务类(例如“NetTransaction”)应保留所有活动事务的私有静态列表,并应将结果处理函数存储在事务完成时要调用的私有实例变量中(结果为on)状态,或超时)。请注意,此处理程序是统一的,因此它处理所有类型的结果(成功/错误/超时/取消)。
在事务类的构造函数中,将“this”新实例添加到活动事务列表中,如果指定了非零超时,则启动超时计时器(添加指向下面描述的cancelTransaction函数的事件侦听器),然后执行网络呼叫最后一次。
完成事务(成功/错误/超时/取消)后,将其从活动事务列表中删除,取消超时计时器(如果已设置),最后将有意义的结果转发给结果处理函数。
使这一切工作的技巧是你必须在事务类中创建结果和状态处理函数,并将THOSE传递给你对NetConnection的调用。这两个函数将负责拦截网络结果(结果或状态),完成事务(如上所述),并将统一结果转发给传递给构造函数的REAL结果处理函数。
这是基本NetTransaction类的基本必需品的内部细分。我的实现有更多的东西,包括生成事务ID(只是一个简单的静态计数器,一个通过id号查找活动事务的方法。它还有事务数据对象的可覆盖的get / set方法,所以我可以自动包装头/解包从NetTransaction派生的类中的自定义数据协议(例如WidgetNetTransaction)。
static private var active_transactions:Array = new Array(); //active network requests pending a result
static private var transaction_count:int = 0; //incremented each time a NetTransaction instance is created so each one can have a unique transaction id number assigned to it
private var transaction_id:int; //Transaction identifier, which may assist a widget in managing its own concurrent transactions. It comes from a static field, auto-incremented in the NetTransaction constructor, so it is always unique for each NetTransaction within the current session... unless more than 2147483648 transactions occur in a single session and the value wraps around, but by then, old transactions wil be forgotten and there shouldn't be any problems as a result.
private var description:String; //an optional description string to describe the transaction or what it is supposed to do (especially for error-reporting purposes).
private var request_data:Object; //this stores the data that will be forwarded to your web server
private var result_handler:Function; //this is the method to be called after intercepting a result or status event. it's left public, because it's acceptable to modifiy it mid-transaction, although I can't think of a good reason to ever do so
private var internal_responder:Responder; //internal responder attached to the transaction
private var timeout:int;
private var timeout_timer:Timer;
//Constructor
public function NetTransaction( network_service:NetworkService, request_data:Object, result_handler:Function = null, description:String = null, timeout:int = 0 )
{
//Throw something a little more friendly than a null-reference error.
if (network_service == null)
throw new ArgumentError( "A NetworkService object must be specified for all NetTransaction objects." );
if (timeout < 0)
throw new ArgumentError( "Timeout must be 0 (infinite) or greater to specify the number of milliseconds after which the transaction should be cancelled.\rBe sure to give the transaction enough time to complete normally." );
//Save information related to the transaction
this.result_handler = result_handler;
this.request_data = request_data;
this.internal_responder = new Responder( net_result, net_status ); //should use override versions of these methods
this.description = description;
this.timeout = timeout;
this.timeout_timer = null;
//Grab a new transaction id, add the transaction to the list of active transactions, set up a timeout timer, and finally call the service method.
this.transaction_id = transaction_count++;
active_transactions.push( this ); //transaction is now registered; this is done BEFORE setting the timeout, and before actually sending it out on the network
if (timeout > 0) //zero, represents an infinite timeout, so we'll only create and start a timer if there is a non-zero timeout specified
{
timeout_timer = new Timer( timeout, 1 );
timeout_timer.addEventListener( TimerEvent.TIMER, this.cancelTransaction, false, 0, true );
timeout_timer.start();
}
network_service.call( internal_responder, request_data );
}
//Finalizes a transaction by removing it from the active transactions list, and returns true.
//Returns false to indicate that the transaction was already complete, and was not found in the active transactions list.
private function completeTransaction():Boolean
{
var index:int = active_transactions.indexOf( this );
if (index > -1)
{
active_transactions.splice( index, 1 );
if (timeout_timer != null)
{
timeout_timer.stop();
timeout_timer.removeEventListener( TimerEvent.TIMER, this.cancelTransaction, false );
}
return true;
}
else
{
//Transaction being removed was already completed or was cancelled
return false;
}
}
//An instance version of the static NetTransaction.cancelTransaction function, which automatically passes the transaction instance.
public function cancelTransaction( details_status_object:Object = null )
{
NetTransaction.cancelTransaction( this, details_status_object );
}
//Cancels all active transactions immediately, forcing all pending transactions to complete immediately with a "NetTransaction.Call.Cancelled" status code.
static public function cancelAllActiveTransactions( details_status_object:Object )
{
for each (var transaction:NetTransaction in active_transactions)
transaction.cancelTransaction( details_status_object );
}
//Cancels the transaction by spoofing an error result object to the net_status callback.
static public function cancelTransaction( transaction:NetTransaction, details_status_object:Object )
{
//Build cancel event status object, containing somewhat standard properties [code,level,description,details,type].
var status:NetTransactionResultStatus = new NetTransactionResultStatus(
"NetTransaction.Call.Cancelled",
"error", //cancelling a transaction makes it incomplete, so the status level should be "error"
"A network transaction was cancelled. The description given for the transaction was: " + transaction.description,
details_status_object, //include, in the details, the status object passed to this method
"" //no type specified
);
//Call the net_status handler directly, passing a dynamic Object-typed version of the NetTransactionResultStatus to the net_status handler.
transaction.net_status( status.ToObject() );
}
//Result responder. Override, then call when you're ready to respond to pre-process the object returned to the result_handler.
protected function net_result( result_object:Object ):void
{
if (completeTransaction())
if (result_handler != null)
result_handler.call( null, new NetTransactionResult( this, result_object, null ) );
}
//Status responder. Override, then call when you're ready to respond to pre-process the object returned to the result_handler.
protected function net_status( status_object:Object ):void
{
if (completeTransaction())
if (result_handler != null)
result_handler.call( null, new NetTransactionResult( this, null, NetTransactionResultStatus.FromObject( status_object ) ) );
}
NetTransactionResult和NetTransactionResultStatus类只是我设置的简单数据类,用于将类型安全的结果发送到统一的结果处理函数。如果NetTransactionResult具有非null状态属性,它会将结果解释为错误,否则,它会将结果解释为成功并使用包含的数据。您看到的NetworkService类只是处理指定调用路径的NetConnection类的包装器,还处理所有低级NetConnection错误事件,与NetTransaction类兼容的包状态消息,最后调用cancelAllTransactions。
这种设置的优点在于,现在无论发生什么样的错误,包括超时,总是会调用事务的结果处理程序,并且需要处理结果所需的所有信息(成功/错误/超时/取消)。这使得使用NetConnection对象几乎与调用本地函数一样简单可靠!
答案 1 :(得分:0)
不是真的。除非您在指定的时间后编写自己的中止功能,否则使用Timer对象(或更好的GCSafeTimer对象,如果您不知道该对象,请将其谷歌)。