Chinaunix首页 | 论坛 | 博客
  • 博客访问: 218480
  • 博文数量: 68
  • 博客积分: 2510
  • 博客等级: 少校
  • 技术积分: 695
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-19 21:17
文章分类

全部博文(68)

文章存档

2009年(16)

2008年(12)

2007年(27)

2006年(13)

我的朋友

分类: 系统运维

2007-12-02 11:53:25

15章客户端数据通信
本地连接:同时在同一机子上,几个运行的swf之间的通信
共享对象:存取客户机上保存的数据
外接接口:与主机环境通信,让flex应用作为整个应用一部分
一、本地连接
可让几个SWF之间互相通信,即使它们运行在分离的FLASH PLAYER实例中,可让FLASH9与以前版本的.SWF之间通信。本地连接使用AMF,一种二进制消息格式。用于本地连接的AMF包的最大尺寸是40kb,本地连接只用AMF0,而不是象其他AS类使用AMF0和AMF3.使用AMF0可以老版本的Flash内容通信。
技术上,也可在一个swf文件内部使用本地连接,但一般是两个swf之间的通信。
Example 15-1. Local connection send example

   
       
            import flash.net.LocalConnection;
            private var _localConnection:LocalConnection = new LocalConnection();
            private function sendMessage(event:MouseEvent):void {
                _localConnection.send("dataChannel", "displayMessage", message.text);
            }
        ]]>
   
   
       
       
   

Example 15-2. Local connection receive example

initialize="initializeHander(event)">
   
       
            import flash.net.LocalConnection;
            private var _localConnection:LocalConnection;
            private function initializeHandler(event:Event):void {
                _localConnection = new LocalConnection();
                _localConnection.connect("dataChannel");
                _localConnection.client = this;    //指定接收消息的对象
            }
              // Note that this method is declared as public because it is
              // exposed as a method to a local connection.
            public function displayMessage(message:String):void {
                output.text += message + "\n";
            }
        ]]>
   
   
跨域通信
默认的,不允许本地连接在从不同域载入的swf间通信.除非显示地指定跨域通信。分为
已知域间的通信
 var localConnection:LocalConnection = new LocalConnection();
     localConnection.send("", "exampleMethod");  //向b.com发送
var receivingLocalConnection:LocalConnection = new LocalConnection();
     receivingLocalConnection.allowDomain("");   //接收a.com的
     receivingLocalConnection.connect("channel");
     receivingLocalConnection.client = this;
未知域间的通信
// Sending .swf
     var localConnection:LocalConnection = new LocalConnection();
     localConnection.send("_channel", "exampleMethod");  //channel要加前缀
     // Receiving .swf
     var receivingLocalConnection:LocalConnection = new LocalConnection();
     receivingLocalConnection.allowDomain("*");   //使用*来表示未定域
     receivingLocalConnection.connect("channel");
     receivingLocalConnection.client = this;
二、持续的数据
Flasp Player不能随意地在客户机上写文件,但Flash Player有一个客户机上被设计的区域,能写入非常特定的文件,叫做Local shared object本地共享对象,能用AS来读写这些文件。使用flash.net.SharedObject类管理访问这些,通过SharedObject接口。
注意:SharedObject类也被用于远程共享对象,所以SharedObject类的API很多特性在这里并没有讨论。远程共享对象允许实时的同步许多客户端,但也需要服务端软件如Flash Media Server。
创建共享对象:
不象许多AS类,不能直接使用ShareObject构造器。而是使用工厂化方法getLocal():
var sharedObject:SharedObject = SharedObject.getLocal("example");参数对应客户机上的文件,有则打开,没有则创建。
sharedObject.data.hideStartScreen = true;使用点句法访问其中保存hideStartScreen的数据
sharedObject.data["First Name"] = "Bob"; 或者使用数组方式
这些数据只是写入了shareObject对象,在swf文件关闭时才写入文件,如果要明确写入:
try {
       sharedObject.flush();
      }
     catch {
       Alert.show("You must allow local data storage.");
      }
下面的例子,是对flush的更详细的介绍,包括它返回的值,具体如何处理返回的结果等。没完全看明白。

initialize="initializeHandler(event)">
   
       
            import flash.net.SharedObject;
            import mx.controls.Alert;
            private var _sharedObject:SharedObject;
。。。。。。
默认,存储共享对象的空间,缺省的分配是100KB,如果超过,Flash Player提示用户分配更多的空间,或者你可事先指定:
sharedObject.flush(512000);
控制范围
默认,每一个本地共享对象特定于它的源.swf。若要允许几个.swf访问相同的共享对象,需要在调用getLocal()时指定路径参数。
如:
默认创建的共享对象:
var sharedObject:SharedObject = ShareObject.getLocal("example");
与默认创建的同名共享对象
var sharedObject:SharedObject = ShareObject.getLocal("example");
并不相同,若要它们访问相同的共享对象,必须指定路径参数为它们的相同部分:
var sharedObject:SharedObject = ShareObject.getLocal("exmaple","/flex/client");
同理:如果要这个域下的所有.swf都要访问相同的共享对象,则只能指定路径参数为"/"了。
在不同域的swf文件是不能访问相同的本地共享对象的。
接着是一个例子,使用本地共享对象,进行用户验证,在原书P366,是个好例子,看得不是完全明白。
定制的序列化
许多内建的数据类型能够被自动地序列化和反序列化,对于定制类型,Flash Player也能自动地序列化所有的public属性(包括getter和setter),但,Flash Player不自动地存储类型,当从共享对象中取回数据时,默认的,它将不能反序列化定制的类型。
以下一大段例子,讲解问题及解决的方法P368。。。。。
三、与主机应用通信
使用flash.external.ExternalInterface可在flex应用与主机应用间互相通信。
ExternalInterface.call("alert","Test message from Flex");在flex里调用javascript的alert方法
var option:Boolean = ExternalInterface.call("confirm","Do yo really want to close the application?");还可从中返回值。
在javascript里调用flex的函数
在flex中为被调用的方法指定别名:
ExternalInterface.addCallback("showAlert",Alert.show);
在javascript中,先要获得要调用swf的引用,使用如下的函数:
function getFlexApplicationReference() {
       if (navigator.appName.indexOf("Microsoft") != -1) {
         return window.Example;   //对于IE浏览器,Example指的是标签的id参数
       } else {
         return document.Example;  //对于非IE浏览器,Example指的是标签的name属性。
       }
     }
然后使用该引用和方法别名就可调用这个方法了:
getFlexApplicationReference().showAlert("Alert message from host application");
例子:设置web浏览器的状态条
(本例可能不适用于firefox的缺省配置,因为firefox默认不允许javascript访问window.status)
在MXML中:
private function rollOverHandler(event:MouseEvent):void {
                ExternalInterface.call("setStatus", event.currentTarget.label);
            } //将当前组件的label值放到浏览器状态条上
在javascript中:
function setStatus(value) {
         window.status = value;
       }
例子:在HTML和Flex表单间交互
本例很实用,在html的表单中使用flex的组件,
下面是HTML部分
Example 15-14. ExternalInterface example HTML page

   
          //用一个框来决定是否启用flex的日期选择器    
                  id="Flex2" width="175" height="180"
            codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.
cab">
           
           
           
           
                            width="175" height="180" name="Flex2" align="middle"
                play="true"
                loop="false"
                quality="high"
                allowScriptAccess="sameDomain"
                type="application/x-shockwave-flash"
                pluginspage="">
           
   


Example 15-15. ExternalInterface example MXML Flex2.mxml

initialize="initializeHandler(event)" width="175" height="180">
   
       
            private function initializeHandler(event:Event):void {
                var disallowedDates:Array = ExternalInterface.call("getDisallowedDates"); //由javascript中获得日期组件的初始参数
                calendar.disabledRanges = disallowedDates;
                ExternalInterface.addCallback("setEnabled", setEnabled); //注册一下可被javascript调用的函数
            }
            public function setEnabled(value:Boolean):void {
                calendar.enabled = value;
            }
        ]]>
   
   

本章结束
阅读(1813) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~