与其他 Flash Player 和 AIR 实例通信Flash Player 9 和更高版本,Adobe AIR 1.0 和更高版本 LocalConnection 类支持在 Adobe® AIR® 应用程序之间以及在浏览器中运行的 SWF 内容之间进行通信。您也可以使用 LocalConnection 类在 AIR 应用程序与在浏览器中运行的 SWF 内容之间进行通信。使用 LocalConnection 类,您可以构建能在 Flash Player 和 AIR 实例之间共享数据的通用应用程序。 关于 LocalConnection 类LocalConnection 类用于开发 SWF 文件,这些文件无需使用 fscommand() 方法或 JavaScript 即可向其他 SWF 文件发送指令。LocalConnection 对象只能在同一客户端计算机上运行的 SWF 文件间进行通信,但是它们可以在不同的应用程序中运行。例如,虽然放映文件维护本地信息,而基于浏览器的 SWF 文件进行的是远程连接,但在浏览器中运行的 SWF 文件和在放映文件中运行的 SWF 文件可以共享信息。(放映文件是以可作为独立应用程序运行的格式保存的 SWF 文件 — 即,放映文件嵌入在可执行文件中,因此不需要安装 Flash Player。) 可以使用 LocalConnection 对象在使用不同 ActionScript 版本的 SWF 之间进行通信:
Flash Player 可自动处理不同版本 LocalConnection 对象间的通信。 最简便的 LocalConnection 对象使用方法是只允许位于同一个域或同一 AIR 应用程序中的 LocalConnection 对象之间进行通信。这样,您就不必担心安全问题了。但如果您需要在不同域之间进行通信,则可采用多种方法来实施安全措施。有关详细信息,请参阅用于 Adobe Flash Platform 的 ActionScript 3.0 参考中列出的 send() 方法的 connectionName 参数和 LocalConnection 类中的 allowDomain() 和 domain 条目的介绍。 可以使用 LocalConnection 对象在一个 SWF 文件中收发数据,但是 Adobe 不建议这样做。而推荐使用共享对象。 可以使用三种方式将回调方法添加到 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); } } } 添加回调方法的第三种方式是创建动态类并动态附加该方法,这与在早期版本的 ActionScript 中使用 LocalConnection 类非常相似,如下面的代码所示: 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"); } } } } 此代码首先创建一个名为 lc 的 LocalConnection 对象,然后将 client 属性设置为对象 clientObject。当其他应用程序调用此 LocalConnection 实例中的方法时,运行时会在 clientObject 对象中查找此方法。 如果已存在具有指定名称的连接,则会引发 Argument Error 异常,指出由于已经连接了该对象,连接尝试失败。 当 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 错误,指出由于已经连接了该对象,连接尝试失败。 以下代码段说明如何创建名为 conn1 的 LocalConnection:
try { connection.connect("conn1"); } catch (error:ArgumentError) { trace("Error! Server already exists\n"); } 从辅助应用程序连接到主应用程序要求您首先在发送 LocalConnection 对象中创建一个 LocalConnection 对象;然后使用连接名称和要执行的方法名称来调用 LocalConnection.send() 方法。例如,要向您早期创建的 LocalConnection 对象发送 doQuit 方法,可使用以下代码:
sendingConnection.send("conn1", "doQuit"); 此代码使用连接名称 conn1 连接到现有 LocalConnection 对象,并调用远程应用程序中的 doMessage() 方法。如果想要将参数发送到远程应用程序,可以在 send() 方法中的方法名称后指定附加参数,如以下代码段所示: sendingConnection.send("conn1", "doMessage", "Hello world"); 连接到不同域中的内容和 AIR 应用程序若要只允许从特定域进行通信,可以调用 LocalConnection 类的 allowDomain() 或 allowInsecureDomain() 方法,并传递包含允许访问此 LocalConnection 对象的一个或多个域的列表,以便传递允许的一个或多个域名。 在早期版本的 ActionScript 中,LocalConnection.allowDomain() 和 LocalConnection.allowInsecureDomain() 是必须由开发人员实现的、且必须返回布尔值的回调方法。在 ActionScript 3.0 中,LocalConnection.allowDomain() 和 LocalConnection.allowInsecureDomain() 都是内置方法,开发人员可以像调用 Security.allowDomain() 和 Security.allowInsecureDomain() 那样调用这两个内置方法,传递要允许的一个或多个域的名称。 Flash Player 8 对本地 SWF 文件引入了安全限制。可以访问 Internet 的 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 对象的内容更易于在域之间移植。下面是两种可能的情形:
Adobe AIR要与在 AIR 应用程序安全沙箱中运行的内容(随 AIR 应用程序一起安装的内容)通信,必须将可标识 AIR 应用程序的超级域用作连接名称的前缀。超级域字符串以 app# 开头,然后依次是应用程序 ID、点 (.)字符和发行商 ID(如果已定义)。例如,在 ID为 com.example.air.MyApp 且没有发行商 ID 的应用程序中,connectionName 参数中使用的正确超级域为 "app#com.example.air.MyApp"。因此,如果基础连接名称为“appConnection”,则应在 connectionName 参数中使用的整个字符串为 "app#com.example.air.MyApp:appConnection"。如果应用程序包含发行商 ID,则必须将该 ID 也包含在超级域字符串中,即 "app#com.example.air.MyApp.B146A943FBD637B68C334022D304CEA226D129B4.1"。 当您允许其他 AIR 应用程序通过本地连接与您的应用程序通信时,必须调用 LocalConnection 对象的 allowDomain() 来传入本地连接域名。对于 AIR 应用程序,此域名的形式与连接字符串相同,都包含了应用程序 ID 和发行商 ID。例如,如果发送方 AIR 应用程序的应用程序 ID 为 com.example.air.FriendlyApp 且发行商 ID 为 214649436BD677B62C33D02233043EA236D13934.1,则用于允许此应用程序进行连接的域字符串为:app#com.example.air.FriendlyApp.214649436BD677B62C33D02233043EA236D13934.1。(自 AIR 1.5.3 起,并不是所有 AIR 应用程序都包含发行商 ID。) |
|