Чтобы выполнить функцию очистки Flex, когда браузер закрыт пользователем

У меня есть клиентское приложение Flex. Мне нужна функция очистки для запуска во Flex, когда пользователь закрывает браузер. Я нашел следующее решение в сети, но оно работает для меня только наполовину. Как я мог это исправить? Заранее спасибо за любые ответы!

симптомы

  • CustomEvent срабатывает, но не выполняется.
    >> EventHandler для CustomEvent.SEND_EVENTS определяется Mate EventMap. Все, что делает обработчик, это вызывает HTTPServiceInvoker, В консоли отладки я вижу, как запускается обработчик и HTTPServiceInvoker, но ни resultHandlers ни faultHandlers были позваны. Я знаю, что этот обработчик событий не имеет проблем, потому что, когда я отправляю тот же CustomEvent.SEND_EVENTS в обработчике нажатия кнопки он ведет себя точно так, как я ожидал)
  • Похоже, что браузер ожидает завершения функции cleanUp, прежде чем он закроется. (все следы были напечатаны до закрытия браузера)

Код

Я добавил следующее в index.template.html

window.onbeforeunload = clean_up;

function clean_up()
{
 var flex = document.${application} || window.${application};
 flex.cleanUp();
}

И использовал следующее в файле приложения MXML

import flash.external.ExternalInterface;

public function init():void {
ExternalInterface.addCallback("cleanUp",cleanUp);
}

public function cleanUp():void {   

   var newEvent:CustomEvent = new CustomEvent(CustomEvent.SEND_EVENTS);
   newEvent.requestObj = myFormModel;

   dispatchEvent(newEvent);

   // for testing purposes
   // to see whether the browser waits for Flex cleanup to finish before closing down   
   var i:int;
   for (i=0; i<10000; i++){
        trace(i);
   }    

}

Моя настройка

  • FlexBuilder 3
  • Mate MVC Framework (Mate_08_9.swc)
  • FlashPlayer 10

3 ответа

Решение

К сожалению, не существует надежного способа выполнять такие функции очистки, которые выполняются асинхронно. result/fault события HTTPService происходят асинхронно после cleanUp метод возвращается. Браузер ждет только до onbeforeunload функция (функция js clean_up) возвращает. Если вы не позвоните event.preventDefault() от этой функции страница будет закрыта. Обратите внимание, что при вызове protectDefault() появится всплывающее окно ok/cancel:

Вы уверены, что хотите уйти с этой страницы?

Нажмите OK, чтобы продолжить, или Отмена, чтобы остаться на текущей странице.

Если пользователь выберет ОК, браузер все равно будет закрыт. Вы можете использовать event.returnValue свойство, чтобы добавить пользовательское сообщение в popop.

//tested only in Firefox
window.addEventListener("beforeunload", onUnload, false);
function onUnload(e)
{
   e.returnValue = "Some text that you want inserted between " +
     "'Are you sure' and 'Press OK' lines";
   e.preventDefault();
}

Вы никогда не сможете надежно обнаружить код браузера в 100% случаев. Если вам действительно нужно выполнить действия, то самый безопасный способ действий - это заставить клиентов отправлять на сервер сообщения "Я все еще жив". Сервер должен отслеживать время по клиенту, а когда клиент не отправляет сообщение в течение указанного промежутка времени (с некоторым пространством для маневра), затем выполнять действия по очистке.

Чем дольше вы проводите время, тем лучше, это зависит от того, насколько критичной является очистка. Если вам не терпится подождать 5 минут, это здорово, в противном случае посмотрите на 1 минуту или 30 секунд или все, что требуется для вашего приложения.

Альтернативный способ очистить сеанс на стороне клиента - использовать JavaScript и external.interface класс в as3. Вот пример кода:

JavaScript:

function cleanUp()
{

    var process;
    var swfID="customRightClick";
    if(navigator.appName.indexOf("Microsoft") != -1){
        process = window[swfID];
        }else
    {
        process = document[swfID];
    }
    process.cleanUp();
}

и в классе as3, где определена функция очистки, используйте это:

import flash.external.ExternalInterface;

if (ExternalInterface.available)
{
    ExternalInterface.addCallback("cleanUp", cleanUp);
}

function cleanUp():void {// your code }
Другие вопросы по тегам