Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Контроль запуска некоторых копий приложения (http://www.flasher.ru/forum/showthread.php?t=159789)

mikhailk 05.07.2011 15:05

Контроль запуска некоторых копий приложения
 
Вопрос - как сделать попроще контроль запуска нескольких копий в рамках одной сессии (на нескольких вкладках одного браузера) и в рамках разных сессий (в разных браузерах). Задача защиты не стоит, поскольку пользователь все равно никаких бонусов не получает (сервер откидывает неразрешенные запросы).

Vier 05.07.2011 15:15

Флеш куки же. Если я правильно понял задачу.

kackbip 05.07.2011 15:20

С помощью LocalConnection можно контролировать все запущенные экземпляры приложения на одной машине.

mikhailk 05.07.2011 15:38

Цитата:

Сообщение от Vier (Сообщение 1008892)
Флеш куки же. Если я правильно понял задачу.

да, вроде

gloomyBrain 05.07.2011 15:51

Цитата:

да, вроде
Да вроде нет =) Используй localConnection

Код AS3:

package ugo.net.connections.unique 
{
        import flash.errors.IllegalOperationError;
        import flash.events.AsyncErrorEvent;
        import flash.events.SecurityErrorEvent;
        import flash.net.LocalConnection;
        import ugo.events.RemovableEventDispatcher;
 
 
        /**
        * Такая флешка уже запущена
        */

        [Event(name="flashAlreadyStarted", type="ugo.net.connections.unique.UniqueFlashControllerEvent")]
 
        /**
        * Запущен еще один экземпляр флешки.
        */

        [Event(name="secondFlashStarted", type="ugo.net.connections.unique.UniqueFlashControllerEvent")]
 
        /**
        * Контроллер уникальности запущенных флешек.
        *
        * Использование:
        *
        * UniqueFlashController.addEventListener(UniqueFlashControllerEvent.FLASH_ALREADY_STARTED, function (e:Event):void { trace("Эта флешка запущена вторично"); } );
        * UniqueFlashController.addEventListener(UniqueFlashControllerEvent.SECOND_FLASH_STARTED , function (e:Event):void { trace("Запущена вторая флешка"); } );
        * UniqueFlashController.init("myConnectionName");
        *
        * @author strax
        */

        public class UniqueFlashController
        {
                private static var _instance:UniqueFlashController = null;
 
                private static const _dispatcher:RemovableEventDispatcher= new RemovableEventDispatcher;
 
 
                private var _connectionName:String;
                private const _connection:LocalConnection = new LocalConnection;
 
                /**
                * Проинициализировать контроллер уникальности флешки.
                *
                * @param connectionName        имя соединения
                */

                public static function init( connectionName:String ):void
                {
                        if( UniqueFlashController._instance )
                                throw new IllegalOperationError("Контроллер уникальности флешки уже проинициализирован.");
                        if(!connectionName )
                                throw new ArgumentError( "Необходимо задать имя соединения." );
 
                        UniqueFlashController._instance = new UniqueFlashController( new UniqueFlashControllerEnforcer(), connectionName );
                }
 
                /**
                * Для получения экземпляра используется статическое свойство instance!
                */

                public function UniqueFlashController(enforcer:UniqueFlashControllerEnforcer, connectionName:String)
                {
                        super();
                        if(!enforcer) throw new ArgumentError("Для создания экземпляра необходим приватный ключ!");
 
                        _connectionName = connectionName;
 
                        _connection.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onAsyncError);
                        _connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecutiryError);
                        _connection.allowDomain("*");
 
                        try
                        {
                                _connection.connect( connectionName );
                        }
                        // если в результате попытки соединиться была получена ошибка, значит такое соединение уже существует.
                        // значит, эта флешка является уже не первой запущенной
                        catch( error:Error )
                        {
                                _dispatcher.dispatchEvent( new UniqueFlashControllerEvent( UniqueFlashControllerEvent.FLASH_ALREADY_STARTED ));
 
                                // вызвать в первой запущенной флешке AsyncError
                                _connection.send( connectionName, connectionName );
                        }
                }
 
                private function onSecutiryError(event:SecurityErrorEvent):void
                {
                        return;
                }
 
                /**
                * Обработать AsyncError.
                *
                * Эта ошибка возникает при попытке вызвать несуществующий метод через LocalConnection.
                * Соответственно, если кто-то пытается вызвать этот метод, значит запущена вторая флешка.
                */

                private function onAsyncError(event:AsyncErrorEvent):void
                {
                        _dispatcher.dispatchEvent( new UniqueFlashControllerEvent( UniqueFlashControllerEvent.SECOND_FLASH_STARTED ));
                }
 
                /**
                * Имя соединения, которое используется для проверки единичного запуска флешки
                */

                public static function get connectionName():String
                {
                        if( _instance )
                                return _instance._connectionName;
                        else
                                return null;
                }
 
                /**
                * @inheritDoc
                */

                public static function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
                {
                        _dispatcher.addEventListener( type, listener, useCapture, priority, useWeakReference );
                }
 
                /**
                * @inheritDoc
                */

                public static function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void
                {
                        _dispatcher.removeEventListener(type, listener, useCapture);
                }
 
                /**
                * Удалить всех слушателей
                */

                public static function removeAllListeners():void
                {
                        _dispatcher.removeAllListeners();
                }
        }
 
}
 
class UniqueFlashControllerEnforcer {}

Код AS3:

package ugo.net.connections.unique 
{
        import flash.events.ErrorEvent;
 
        /**
        * Событие контроллера уникальных флешек.
        *
        * @author strax
        */

        public class UniqueFlashControllerEvent extends ErrorEvent
        {
                /**
                * Такая Флешка уже запущена.
                *
                * Это сообщение получает флешка, которая пытается запуститься вторично.
                */

                public static const FLASH_ALREADY_STARTED:String = "flashAlreadyStarted";
 
                /**
                * Запущена вторая флешка.
                *
                * Это событие получает первая запушенная флешка при запуске второй.
                */

                public static const SECOND_FLASH_STARTED:String = "secondFlashStarted";
 
                public function UniqueFlashControllerEvent(type:String)
                {
                        super(type, false, false, (type == FLASH_ALREADY_STARTED?"SWF уже запущена":"Запущен еще один экземпляр SWF"));
                }
 
        }
 
}

Автор шедевра - товарищ по работе. Не уверен, что он помнит свой пароль от flasher.ru, поэтому запостил сам. Кстати, претензии тоже к нему =)

Rzer 05.07.2011 17:32

Код AS3:

 
try{
  oneInstanceControl = new LocalConnection();
  oneInstanceControl.client = this;
  oneInstanceControl.connect("gameInstanceControl");
} catch(err:ArgumentError){
  Alert.show("Игра уже запущена в другой вкладке или браузере", null, "Ошибка");
  return;
}

Недостаток, метода через LocalConenction - если браузер упадёт с критической ошибкой, то локалКонекшн повиснет и не даст запускать копии до перезагрузки компьютера.

kackbip 05.07.2011 17:38

Не знал о такой особенности LocalConnection.
Тогда может и локальный SharedObject можно заюзать.

~~~ 05.07.2011 20:01

Товарищи, вставлю свои пять копеек:
У LocalConnection есть особенность - лимит на "соединения", что по-сути есть выделение памяти на объединённые "ячейки" памяти. Лимит этот от машины к машине различен. Но можно определить переполнение группы. Группа - это все екземпляры LocalConnection, единожды пытавшиеся подключиться к одному каналу (или создать его). Определяется двойной проверкой, e.g.:
Код AS1/AS2:

var uniqueness:Boolean;
try
{
  new LocalConnection().connect("gameInstanceControl");
  uniqueness = true;
}
catch(e:Error)
{
  try
  {
      new LocalConnection().connect("gameInstanceControl");
      // вот тут однозначно переполнение, а значет канал уже занят
      uniqueness = false;
  }
  catch(e:Error)
  {
      // переполнения группы нет, уникальность подтверждена
      uniqueness = true;
  }
}

П.с.: средний лимит, судя по моим тестам, примерно 7-8 пиров на группу.
Прошу простить такую терминологию. Я написал большущую комплексную работу, в состав которой входит и эта метода, но всё для компании и под грифом секретно.
И да, лучший способ проверки - комбинация этого способа и SO, но с SO надо ещё осторожнее работать.

Добавлено через 2 минуты
Да, про использование SO: в нём удобно хранить имя канала и даты последней его генерации и забора.


Часовой пояс GMT +4, время: 20:33.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.