Связь с другими экземплярами Flash Player и AIR

Flash Player 9 и более поздних версий, Adobe AIR 1.0 и более поздних версий

Класс LocalConnection позволяет устанавливать связь между приложениями Adobe® AIR®, а также между содержимым SWF, выполняющимся в браузере. Можно также использовать класс LocalConnection для установления связи между приложением AIR и содержимым SWF, выполняющимся в браузере. Класс LocalConnection позволяет создавать легко приспосабливаемые приложения, поддерживающие обмен данными между экземплярами Flash Player и AIR.

О классе LocalConnection

Класс LocalConnection позволяет создавать SWF-файлы, которые могут отправлять инструкции другим SWF-файлам, не используя метод fscommand() или JavaScript. Объекты LocalConnection могут поддерживать связь только с SWF-файлами, выполняемыми на одном клиентском компьютере, но, возможно, в разных приложениях. Например, SWF-файл, выполняемый в браузере, и SWF-файл, выполняемый в проекторе, могут обмениваться информацией, если проектор содержит локальные сведения, а SWF-файл в обозревателе подключается удаленно. (Проектор — это SWF-файл, сохраненный в формате, который позволяет ему работать в качестве автономного приложения, то есть для проектора не требуется установка проигрывателя Flash Player, так как он встроен в исполняемый файл.)

Объекты LocalConnection можно использовать для поддержания связи между SWF-файлами, созданными с помощью разных версий ActionScript:

  • Объекты ActionScript 3.0 LocalConnection могут поддерживать связь с объектами LocalConnection, созданными в версиях ActionScript 1.0 и 2.0.

  • Объекты LocalConnection версии ActionScript 1.0 или 2.0 могут поддерживать связь с объектами LocalConnection, созданными в версии ActionScript 3.0.

Проигрыватель Flash Player автоматически обрабатывает такую связь между объектами LocalConnection разных версий.

Самым простым способом использования объекта LocalConnection является разрешение установления связи только между объектами LocalConnection, расположенными в том же домене или в том же приложении AIR. В этом случае не нужно беспокоиться о безопасности. Однако если нужно разрешить установление связи между доменами, следует принять меры безопасности. Дополнительные сведения см. в обсуждении параметра connectionName метода send() и в описаниях allowDomain() и domain в классе LocalConnection в cправочнике ActionScript® 3.0 для платформы Adobe® Flash® Platform .

Объекты LocalConnection можно использовать для отправки и получения данных в одном SWF-файле, но компания Adobe не рекомендует это делать. Вместо этого используйте общие объекты.

Существует три способа добавлять методы обратного вызова в объекты LocalConnection:

  • создать подкласс для LocalConnection и добавить методы;

  • задать в качестве значения свойства LocalConnection.client объект, реализующий методы;

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

Первый способ добавления методов обратного вызова подразумевает создание подкласса для LocalConnection. Необходимо определить методы в пользовательском классе, а не добавлять их динамически в экземпляр LocalConnection. Этот подход демонстрируется на примере следующего кода.

package 
{ 
    import flash.net.LocalConnection; 
    public class CustomLocalConnection extends LocalConnection 
    { 
        public function CustomLocalConnection(connectionName:String) 
        { 
            try 
            { 
                connect(connectionName); 
            } 
            catch (error:ArgumentError) 
            { 
                // server already created/connected 
            } 
        } 
        public function onMethod(timeString:String):void 
        { 
            trace("onMethod called at: " + timeString); 
        } 
    } 
}

Чтобы создать новый экземпляр класса CustomLocalConnection, необходимо использовать следующий код:

var serverLC:CustomLocalConnection; 
serverLC = new CustomLocalConnection("serverName");

Второй способ добавления методов обратного вызова подразумевает использование свойства LocalConnection.client . Для этого нужно создать пользовательский класс и назначить новый экземпляр свойству client , как показано в следующем коде.

var lc:LocalConnection = new LocalConnection(); 
lc.client = new CustomClient();

Свойство LocalConnection.client указывает требуемые методы обратного вызова объекта. В предыдущем коде в качестве значения свойства client был задан новый экземпляр пользовательского класса, CustomClient. Значением по умолчанию для свойства client является текущий экземпляр LocalConnection. Свойство client можно использовать, если имеется два обработчика данных с одинаковыми методами, но разными видами поведения, например в приложении, где кнопка в одном окне переключает вид во втором окне.

Чтобы создать класс CustomClient, можно использовать следующий код:

package 
{ 
    public class CustomClient extends Object 
    { 
        public function onMethod(timeString:String):void 
        { 
            trace("onMethod called at: " + timeString); 
        } 
    } 
}

Третий способ добавления методов обратного вызова подразумевает создание динамического класса и присоединение методов во время выполнения. это очень похоже на использование класса LocalConnection в предыдущих версиях ActionScript, как показано в следующем коде.

import flash.net.LocalConnection; 
dynamic class DynamicLocalConnection extends LocalConnection {}

Методы обратного вызова можно динамически добавлять к этому классу с помощью следующего кода.

var connection:DynamicLocalConnection = new DynamicLocalConnection(); 
connection.onMethod = this.onMethod; 
// Add your code here. 
public function onMethod(timeString:String):void 
{ 
    trace("onMethod called at: " + timeString); 
}

Предыдущий способ добавления методов обратного вызова не рекомендуется, так как полученный с его помощью код не отличается особой портативностью. Кроме того, такой способ создания локальных подключений может вызвать проблемы с быстродействием, так как обращение к динамическим свойствам выполняется намного медленнее, чем обращение к фиксированным свойствам.

Свойство isPerUser

Свойство isPerUser было добавлено в проигрыватель Flash Player (10.0.32) и AIR (1.5.2) для устранения конфликтов, которые возникали, если в компьютер Mac выполнили вход несколько пользователей. В других операционных системах это свойство игнорируется, так как локальное подключение всегда связано с отдельным пользователем. В новом коде свойству isPerUser необходимо присваивать значение true . Однако в целях обеспечения обратной совместимости по умолчанию используется значение false . Это значение по умолчанию может быть изменено в будущих версиях среды выполнения.

Обмен сообщениями между двумя приложениями

Класс LocalConnection используется для связи между различными приложениями AIR, а также между приложениями Adobe® Flash® Player (SWF), выполняющимися в браузере. Можно также использовать класс LocalConnection для установления связи между приложением AIR и приложением SWF, выполняющимся в браузере.

Например, на веб-странице может быть несколько экземпляров Flash Player, или же один экземпляр Flash Player может получать данные из экземпляра Flash Player во всплывающем окне.

Следующий код определяет объект LocalConnection, который выступает в качестве сервера и принимает входящие вызовы LocalConnection от других приложений:
package 
{ 
    import flash.net.LocalConnection; 
    import flash.display.Sprite; 
    public class ServerLC extends Sprite 
    { 
        public function ServerLC() 
        { 
            var lc:LocalConnection = new LocalConnection(); 
            lc.client = new CustomClient1(); 
            try 
            { 
                lc.connect("conn1"); 
            } 
            catch (error:Error) 
            { 
                trace("error:: already connected"); 
            } 
        } 
    } 
}

Этот код сначала создает объект LocalConnection с именем lc и задает для свойства client объект clientObject . Когда другое приложение вызывает метод в этом экземпляре LocalConnection, среда выполнения производит поиск этого метода в объекте clientObject .

Если соединение с таким именем уже существует, возникнет исключение ArgumentError, свидетельствующее о том, что произошла ошибка подключения, так как объект уже подключен.

Каждый раз, когда экземпляр Flash Player подключается к SWF-файлу и пытается вызвать любой метод для указанного локального подключения, запрос отправляется классу, заданному в свойстве client класса CustomClient1.

package 
{ 
    import flash.events.*; 
    import flash.system.fscommand; 
    import flash.utils.Timer; 
    public class CustomClient1 extends Object 
    { 
        public function doMessage(value:String = ""):void 
        { 
            trace(value); 
        } 
        public function doQuit():void 
        { 
            trace("quitting in 5 seconds"); 
            this.close(); 
            var quitTimer:Timer = new Timer(5000, 1); 
            quitTimer.addEventListener(TimerEvent.TIMER, closeHandler); 
        } 
        public function closeHandler(event:TimerEvent):void 
        { 
            fscommand("quit"); 
        } 
    } 
}

Чтобы создать сервер LocalConnection, вызовите метод LocalConnection.connect() и выберите уникальное имя подключения. Если уже имеется подключение с указанным имеем, выводится ошибка ArgumentError, указывающая на сбой попытки подключения, так как объект уже подключен.

Следующий сниппет иллюстрирует создание LocalConnection с именем conn1 :
try 
{ 
    connection.connect("conn1"); 
} 
catch (error:ArgumentError) 
{ 
    trace("Error! Server already exists\n"); 
}
При подключении к основному приложению из второстепенного необходимо сначала создать объект LocalConnection в отправляющем объекте LocalConnection, затем вызвать метод LocalConnection.send() с именем соединения и именем метода, который нужно выполнить. Например, для отправки метода doQuit в объект LocalConnection, созданный ранее, используйте следующий код:
sendingConnection.send("conn1", "doQuit");

Этот код подключается к существующему объекту LocalConnection с именем соединения conn1 и вызывает метод doMessage() в удаленном приложении. Если необходимо отправить параметры удаленному приложению, укажите дополнительные аргументы после имени метода в методе send() , как показано в следующем сниппете:

sendingConnection.send("conn1", "doMessage", "Hello world");

Подключение к содержимому в разных доменах и к другим приложениям AIR

Чтобы разрешить установление связи только с конкретными доменами, необходимо вызвать метод allowDomain() или allowInsecureDomain() класса LocalConnection и передать список имен одного или нескольких доменов, которым предоставлен доступ к данному объекту LocalConnection.

В предыдущих версиях ActionScript методы обратного вызова LocalConnection.allowDomain() и LocalConnection.allowInsecureDomain() должны были реализовываться разработчиками и возвращать логическое значение. В ActionScript 3.0 методы LocalConnection.allowDomain() и LocalConnection.allowInsecureDomain() являются встроенными. Разработчики могут вызывать их так же, как методы Security.allowDomain() и Security.allowInsecureDomain() , передавая одно или несколько имен разрешенных доменов.

В проигрыватель Flash Player 8 были внесены ограничения в сфере безопасности локальных SWF-файлов. SWF-файл, которому разрешен доступ к Интернету, не может иметь доступ к локальной файловой системе. Если задать значение localhost , SWF-файл будет доступен любому локальному SWF-файлу. Если метод LocalConnection.send() попытается установить связь с SWF-файлом из изолированной программной среды, не доступной для вызывающего кода, отправляется событие securityError ( SecurityErrorEvent.SECURITY_ERROR ). Во избежание этой ошибки можно указать домен вызывающей стороны в методе LocalConnection.allowDomain() получателя.

Методам LocalConnection.allowDomain() и LocalConnection.allowInsecureDomain() можно передать два специальных значения: * и localhost . Значение «звездочка» (*) предоставляет доступ из всех доменов. Строка localhost разрешает вызов приложения содержимым, установленным на локальном компьютере, но за пределами каталога ресурса приложения.

При попытке метода LocalConnection.send() установить связь с приложением, находящимся в изолированной программной среде безопасности, к которой вызывающий код не имеет доступа, отправляется событие securityError ( SecurityErrorEvent.SECURITY_ERROR ). Во избежание этой ошибки можно указать домен вызывающей стороны в методе LocalConnection.allowDomain() получателя.

При установлении связи только между содержимым в одном домене можно указать параметр connectionName , который не начинается с символа нижнего подчеркивания ( _ ) и не указывает доменное имя (например, myDomain:connectionName ). Используйте ту же строку в команде LocalConnection.connect(connectionName) .

При установлении связи между содержимым в разных доменах указывается параметр connectionName , который начинается с нижнего подчеркивания. Использование нижнего подчеркивания улучшает перемещаемость содержимого с принимающим объектом LocalConnection между доменами. Вот два возможных случая:

  • Если строка для connectionName не начинается с нижнего подчеркивания, среда выполнения добавляет префикс с именем супердомена и двоеточие (например, myDomain:connectionName ). Хотя это обеспечивает отсутствие конфликтов соединения с одноименными соединениями из других доменов, каждый отправляющий объект LocalConnection должен указывать это имя супердомена (например, myDomain:connectionName ). При перемещении файла HTML или SWF с принимающим объектом LocalConnection в другой домен среда выполнения изменяет префикс в соответствии с новым супердоменом (например, anotherDomain:connectionName ). Все отправляющие объекты LocalConnection необходимо изменить вручную в соответствии с новым супердоменом.

  • Если строка для connectionName начинается с нижнего подчеркивания (например, _connectionName ), среда выполнения не прибавляет к ней префикс. Это значит, что принимающие и отправляющие объекты LocalConnection используют одинаковые строки для connectionName . Если принимающий объект использует LocalConnection.allowDomain() для указания на то, что будут приняты соединения из любого домена, можно переместить файл HTML или SWF с принимающим объектом LocalConnection в другой домен без изменения отправляющих объектов LocalConnection.

    Недостатком использования имен с нижним подчеркиванием в параметре connectionName является возможность конфликтов, например, когда два приложения пытаются подключиться с использованием одного и того же имени connectionName . Второй недостаток, связанный с первым, относится к безопасности. Имена соединений с нижним подчеркиванием не идентифицируют домен прослушивающего приложения. По этой причине предпочтительными именами являются имена с указанием домена.

Adobe AIR

Для обращения к содержимому в изолированной среде приложения AIR (содержимому, установленному вместе с приложением AIR) необходимо использовать префикс для имени подключения, содержащий супердомен, идентифицирующий приложение AIR. Строка супердомена начинается с app# , далее следует идентификатор приложения, а после точки (.) — идентификатор издателя (если он определен). Например, супердомен для параметра connectionName для приложения с идентификатором приложения com.example.air.MyApp и отсутствующим идентификатором издателя выглядит следующим образом: "app#com.example.air.MyApp" . Таким образом, если основное подключение имеет имя appConnection, то в параметре connectionName необходимо использовать строку "app#com.example.air.MyApp:appConnection" . Если для приложения определен идентификатор издателя, то его также необходимо включить в строку супердомена: "app#com.example.air.MyApp.B146A943FBD637B68C334022D304CEA226D129B4.1" .

Если одному приложению AIR разрешается установить связь с другим приложением через локальное соединение, необходимо вызвать метод allowDomain() объекта LocalConnection, передав доменное имя локального соединения. Для приложения AIR доменное имя образуется из идентификаторов приложения и издателя тем же образом, что и строка соединения. Например, если отправляющее приложение AIR имеет идентификатор приложения com.example.air.FriendlyApp и идентификатор издателя 214649436BD677B62C33D02233043EA236D13934.1 , то доменная строка, используемая для разрешения подключения приложения, будет выглядеть так: app#com.example.air.FriendlyApp.214649436BD677B62C33D02233043EA236D13934.1 . (Начиная с AIR 1.5.3 идентификатор издателя присутствует не во всех приложениях AIR.)