Как вы меняете тайм-аут при подключении к flash.net.net? - PullRequest
0 голосов
/ 06 августа 2009

Время ожидания составляет около 10 секунд. Можно ли это изменить?

Ответы [ 2 ]

1 голос
/ 06 сентября 2009

Я не вижу встроенного способа сделать это. Тем не менее, это определенно возможно реализовать самостоятельно.

Просто создайте класс транзакции, представляющий каждый вызов, который вы делаете с экземпляром NetConnection.

Этот класс транзакции, например «NetTransaction», должен хранить закрытый статический список всех активных транзакций и должен хранить функцию обработчика результатов в закрытой переменной экземпляра, которая должна вызываться по завершении транзакции (в результате, в статус или по тайм-ауту). Обратите внимание, что этот обработчик унифицирован, поэтому он обрабатывает все виды результатов (успех / ошибка / тайм-аут / отменен).

В конструкторе вашего класса транзакций добавьте новый экземпляр «this» в список активных транзакций, запустите таймер тайм-аута, если указан ненулевой тайм-аут (добавление прослушивателя событий, указывающего на функцию cancelTransaction, описанную ниже), а затем выполните последний вызов сети.

Когда вы завершите транзакцию (успех / ошибка / тайм-аут / отменена), удалите ее из списка активных транзакций, отмените таймер тайм-аута, если он был установлен, и, наконец, перенаправьте значимый результат в функцию-обработчик результатов.

Хитрость в том, чтобы заставить все это работать, состоит в том, что вы должны создать функции обработчика результата и состояния в классе транзакции и передать ЭТО свой вызов в NetConnection. Эти две функции будут отвечать за перехват сетевого результата (результат или состояние), завершение транзакции (как описано выше) и пересылку унифицированного результата в функцию-обработчик РЕАЛЬНОГО результата, которая была передана конструктору.

Вот урезанные внутренние части базового класса NetTransaction с базовыми потребностями. В моей реализации есть больше вещей, в том числе создание идентификаторов транзакций (простой статический счетчик, метод поиска активной транзакции по номеру идентификатора. Она также имеет переопределяемые методы 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 имеет ненулевое свойство состояния, в противном случае он интерпретирует результат как успех и использует включенные данные. Класс NetworkService, который вы видите, является просто оболочкой для класса NetConnection, который обрабатывает указание пути вызова, а также обрабатывает все низкоуровневые события ошибок NetConnection, упаковывает сообщения о состоянии, совместимые с классом NetTransaction, и, наконец, вызывает cancelAllTransactions.

Прелесть этой настройки в том, что теперь, независимо от того, какая ошибка произошла, включая тайм-ауты, ваш ВСЕГДА будет вызываться ваш обработчик результатов для транзакции со всей информацией, необходимой для обработки результата (success / error / timeout /) отменен). Это делает использование объекта NetConnection почти таким же простым и надежным, как и вызов локальной функции!

0 голосов
/ 20 августа 2009

Не совсем. Если вы не пишете свои собственные функции для прерывания по истечении заданного промежутка времени, используя объект Timer (или, лучше, объект GCSafeTimer, если вы его не знаете, Google его).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...