1. SWF间的通讯——LocalConnection

在同一台机器上运行的两个(或多个)swf,可以使用LocalConnection进行通讯。可以有多个发送端,但接收端只能有一个。
在发送端定义LocalConection,连接接收端通道,使用其send方法发送信息。在接收端定义LocalConnection,打开连接通道,定义信息接收函数。两个flash之间就可以进行通讯了。
示例浅析:
接收端:
//创建接收端本地连接

private var _recive:LocalConnection = new LocalConnection();

//定义连接通道

private var _channel:String = "_connection"

//打开通道

_recive.connect(_channel);

//设置接收者为本身

_recive.client = this;

//定义信息接收方法(由发送端调用)

public function reciveTest(_name:String):void

{

             var _text:TextField = new TextField();

             _text.text = "接收端,收到信息:" + "\n" + "Hello," + _name;

             addChild(_text);

             _text.x = 10, _text.y = 10;

}
发送端:
//创建发送端本地连接

private var _send:LocalConnection = new LocalConnection();

//定义连接通道(名称要与接收端的一致)

private var _channel:String = "_connection";

//建立连接

_send.connect(_channel);

//发送信息,信息接收函数为接收端的reciveTest,传递参数"tata"

_send.send(_channel, "reciveTest", "tata");

//运行时先打开接收端swf,再打开发送端swf。

 
2. Flash 本地共享对象SharedObject

ActionScript 中, SharedObject 类实现了客户端机器数据的持久性存储。本地 local shared objects (LSOs) ,很类似于浏览器中 cookies ,可用于存储用户名,游戏数据等。
LSOs 通过 SharedObject.getLocal 创建或打开。
用法:
var so:SharedObject = SharedObject.getLocal(name:string, localPath:string = null, secure:Boolearn = false);
如果共享对象已存在,将返回 SharedObject 实例,否则根据名字创建新的。可以通过 so.data.someData 的形式向 so 中写入或读取数据。若要删除共享对象的值,要使用 delete 方法,如 delete so.data.someData ,若要删除整个共享对象,则调用其 clear() 方法,如 so.clear()
若要使同一个域的 swf 访问同个本地共享对象,可以通过设置 getLocal 的第二个参数实现。该参数为绝对或相对路径字符串,指定 LSO 的存储位置。
示例浅析:
以不同 swf 访问同个本地共享对象为例
//写入端:
private var writeSO:SharedObject;
//创建本地共享对象mySO
writeSO = SharedObject.getLocal("mySO", "/");
//向共享对象写入数据
writeSO.data.nameInfo = "Hello,tata";

//读取端:
private var readSO:SharedObject;
//打开本地共享对象mySO
readSO = SharedObject.getLocal("mySo", "/");
//从共享对象中读取数据
trace(readSO.data.nameInfo);
3. Flash JS 交互

       ExternalInterface 类允许 Flash 播放器以异步的方式与宿主程序进行通信,宿主程序一般指的是 Web 浏览器。
       ExternalInterface 支持以下浏览器:
Internet Explorer 5.0+ (Windows)
Netscape 8.0+ (Windows and Mac OS X)
Mozilla 1.7.5+ (Windows and Mac OS X)
Firefox 1.0+ (Windows and Mac OS X)
Safari 1.3+ (Mac OS X)
ActionScript 调用 JavaScript 函数,可使用 ExternalInterface.call() 。该方法采用异步调用 JS 函数机制。用法: ExternalInterface.call(JS 方法名: string [,参数 1 *, 参数 2 * ……] ) 。如果 JS 函数有返回值,可用变量存储:如 var str:String = ExternalInterface.call(“jsFunction”);
可以用 ExternalInterface.available 查看浏览器是否支持,若不支持,可使用 navigateToURL() 方法。
用法:
var request:URLRequest = new URLRequest(“javascript:JS 函数 ( 传递参数 )”);
navigateToURL(request);
但使用这个方法没有返回值。
两种方法都在 flash.net 包下。
JavaScript 调用 ActionScript 函数:使用 ExternalInterface.addCallback() 注册 AS 函数,然后在 JS 端进行调用。用法: ExternalInterface.addCallback( 被调用函数对 JS 的别名: strin ,被调用函数: function) 。如: ExternalInterface.addCallback(“helloWordAS”,helloWord);

 

示例浅析:
AS端:
if (ExternalInterface.available)
{
  //注册js回调方法clientFunction,"jsAlias"是clientFunction在js中的别名
  ExternalInterface.addCallback("jsAlias", clientFunction);
        
  if (ExternalInterface.call("isReady"))
  {
    _txt.appendText ("可以发送数据了!")
    sayHello();
  }else {
    _txt.appendText ("等待发送数据...\n");
    setTimeout(sayHello, 2000)    
  }
}
private function sayHello():void
{
  if (ExternalInterface.available)
  {
    //使用ExternalInterface调用js方法jsFunction,传递参数"hello,tata"
    var str:String = ExternalInterface.call("jsFuntion", "hello,tata");
    _txt.appendText(str + "\n");
  }
}
//js回调方法clientFunction
public function clientFunction(str:String):void
{
       _txt.appendText(str+"\n");
}
JS 端:
var jsReady = false;
    
function init()
{
  jsReady = true;
}
function isRead()
{
  return jsReady;
}
    
function jsFuntion(msg)
{
  alert("来自AS的消息:"+msg);
  this.sendToAs();
  return "这是调用jsFunction返回的";
}
    
function thisMovie(movieName)
{
  if (navigator.appName.indexOf("Microsoft") != -1) {    
    return window[movieName];
  } else {
    return document[movieName];
  }
}
    
function sendToAs()
{
  //调用AS方法
  thisMovie("tata").jsAlias("此信息来自JS!");
}
 
先编译出 swf ,再打开 index.html 才能看到结果,因为 flashPlayer 不支持 ExternalInterface ,要有浏览器包装。
 
4. 使用HttpService 连接服务器

       如果想发送数据给服务端脚本,可以创建一个包含数据的 URLRequest 实例,并用 flash.net.sendToURL() flash.net.navigateToURL() 方法发送出去。
用法:
 
var request:URLRequest = new URLRequst(服务端脚本路径:string);
var vars:URLVariables = new URLVariables();
vars.someData = “tata”;
vars.someNumber = 10;
request.data = vars;
request.method = URLRequestMethod.POST或URLRequestMethod.GET;
sendToURL(request);或navigateToURL(request[,”_blank/_self/_parent”]);
示例:
//设置传递参数
var myVars:URLVariables = new URLVariables();
myVars.name = "tata";
        
//创建URLRequest对象
var request:URLRequest = new URLRequest("http://localhost/HttpServerConnect/test.php");
//设置传递模式
request.method = URLRequestMethod.POST;
//设置参数
request.data = myVars;

navigateToURL(request);
默认情况下,数据是通过 HTTP POST 方式传输的, URLRequest method 属性指定数据的传输方式, URLRequestMethod.GET HTTP GET ,而 URLRequestMethod.POST HTTP POST URLRequest data 属性设置要发送的数据,如果是 URLVariables 实例,则发送名称 / 对到服务器,也可以是 flash.util.ByteArray ,通过 HTTP POST 方式传递二进制数据到服务器,或者是 String 类型的数据作为 XML-RPC 请求发送到服务器。
当需要处理服务器返回的结果时,应该使用 URLLoader.load() 方法。通过侦听 Event.COMPLETE 事件,在事件处理函数中处理服务端返回的结果。
用法:
 
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.VARIABLES;
loader.addEventListerner(Event.COMPLETE, loadedHd);
loader.load(request);
示例:
var myVars:URLVariables = new URLVariables();
myVars.name = "tata";
        
var request:URLRequest = new URLRequest("http://localhost/HttpServerConnect/test.php");
request.method = URLRequestMethod.POST;
request.data = myVars;
        
//创建URLLoader对象
var loader:URLLoader = new URLLoader(request);
//设置接收数据方式
loader.dataFormat = URLLoaderDataFormat.VARIABLES;
loader.addEventListener(Event.COMPLETE, loadedHd);
loader.load(request);

private function loadedHd(e:Event):void
{
  trace("Hello,"+e.target.data.flashData);
}
 
服务端:
         $name = $_REQUEST['name'];
         echo "flashData=$name"; //这里注意echo 的数据必须是名称=值的形式。

?>
5. 使用WebService连接服务器

       通过web services,可以使用其他网站提供的服务,完善自己客户端的功能:如加入天气预报,提供在线翻译,股市信息等。
       web services采用异步通讯。在调用web services对外提供的接口之前,要先加载其wsdl
Flash播放器没有内建的web services支持,可以通过导入mx.rpc包引入调用web services方法。
示例浅析:
以调用天气预报接口获取天气预报为例。例子使用的是www.webxml.com.cn提供的天气预报web服务。
//创建webServer对象
private var webSer:WebService;
webSer = new WebService();
//webServer路径
webSer.wsdl= "http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl";
//调用webServer的方法前要加载其wsdl
webSer.loadWSDL();
        
//添加侦听器
webSer.addEventListener(LoadEvent.LOAD, wsdlLoaded);
webSer.addEventListener(ResultEvent.RESULT, resultHandler);
webSer.addEventListener(FaultEvent.FAULT, faultHandler);
wdsl加载完毕后,才能调用webService的方法。在resultHandler事件中处理返回结果,在faultHandler事件中进行错误处理。

//调用webServer提供的外部方法getWeather
webSer.getWeather({theUserID:"",theCityCode:”上海”});
//输出返回结果
private function resultHandler(e:ResultEvent):void
{
for each(var s:* in e.result)
{
  for each(var s2:* in s)
  {
  trace(s2[1]); //输出查询的城市
trace(s2[3]); //输出最后更新时间
    var arr:Array = (s2[4] as String).split(";");
    // 输出具体天气情况
    for (var i:uint = 0; i < arr.length; i++)
    {
      trace(arr[i] + "\n")
    }
    break;
  }
}
}
 
6. 使用Flash Remote 连接服务器

Flash Remoting 通过 HTTP 通讯,采用二进制数据协议,称之为 Active Messaging Format (AMF) 。可以传输更多的数据 ,效率比起 web serverices 更高, 速度更快。 Flash Player. 支持 Flash Remoting
Amfphp是一个 PHPRPC 工具箱。可用于 PHP Flash Flex 之间利用 Remoting 进行交互。

环境配置:

下载安装 php 安装包。

amfphp 安装配置:
1.       下载安装 Amfphp :可以到 http://www.5etdemi.com/uploads/amfphp-1.9.beta.20070126.zip 下载,将其解压到你的 php 网站根目录下。
2.       安装 AMF 扩展:到 http://www.teslacore.it/projects/amfext/amfext-0.8.7a-bin.zip 下载,将 php_amf.dll 解压缩到 php 根路径下的 \ext 中;打开 php.ini ,加上下面这一行: extension = php_amf.dll 。再重启 php 服务器。(如果你安装的 php 安装包已有,可以省略这一步)。

 

Flash 使用 NetConnection 类连接 amfphp ,使用 call 方法调用 php 类函数。
用法:
客户端:
//定义一个nc用于连接AMFPHP
private var nc:NetConnection;
//定义一个responder用于处理客户端调用服务端方法的结果
private var responder:Responder;
//连接路径
private var gateway:String = "http://localhost/amfphp/gateway.php";

nc = new NetConnection();
responder = new Responder(resultHandler, faultHandler);
resultHandler和faultHandler分别是结果处理函数和错误处理函数。
//创建连接
nc.connect(gateway);
//调用服务器方法test,RemoteConnect为ConnectTest.php所在的文件夹,传递参数"tata"
nc.call("RemoteConnect.ConnectTest.test", responder,"tata");
如果不想要responder,可以指定为null;

//结果处理
private function resultHandler(_name:String):void
{
  trace("调用服务器方法返回结果:");
  trace("Hello," + _name);
}
 
服务端:
amfphp 下的 service 目录下新建一文件夹,命名为 RemoteConnect ,在此文件夹下新建一文档,命名为 ConnectTest.php 。这里注意一点,提供给 Flash 调用的类类名要与文件名相同。在 ConnectTest.php 输入以下代码:
class ConnectTest
{
  function test($name)
  {
    return $name;
  }
}
?>
 
7. 使用Socket 连接服务器

Socket 套接字连接允许 Flash 播放器通过指定的端口与服务器通信, socket 连接与其他通信技术最大的不同是 socket 连接在数据传输完成后不会自动关闭。当 socket 连接创建后,连接会一直保持,直到客户端( Flash 播放器)和服务端主动关闭。 Socket 连接被普遍用于创建多用户应用程序。 Socket 通信方式是异步的,也就是说你不能直接从 socket 连接中读取数据,而是通过事件处理函数进行读取处理。——摘自 ActionScript3.0 CookBook
使用 Socket.connect() 方法建立连接。因为是异步通信, connect() 方法不会等待结果而是继续执行下面的语句,因此在连接之前要注册侦听器获取连接结果。
用法:
var _socket:Socket = new Socket();
_socket.addEventListerner(Event.COMNECT,connectHd);
_socket.connect(连接服务器地址:string,端口号:数字);
socket连接的端口号必须大于1024,如果小于则需服务器提供策略文件允许。
示例:
//创建socket对象
private var _socket:Socket
_socket = new Socket();
_socket.addEventListener(Event.CONNECT, onConnected);
_socket.addEventListener(ProgressEvent.SOCKET_DATA, onDataHd);
_socket.connect("localhost",1337);

private function onConnected(e:Event):void
{
  //向缓冲区写入数据
  var message:ByteArray = new ByteArray();
  message.writeMultiByte("tata", "utf-8");
  _socket.writeBytes(message);
  //发送数据
  _socket.flush();
}
    
private function onDataHd(e:ProgressEvent):void
{
  //接收读取数据
  while (_socket.bytesAvailable)
  {
    trace(_socket.readMultiByte(_socket.bytesAvailable , "utf-8"));
  }
}
(示例服务端代码来自
http://www.111cn.cn/phper/30/7cadb3c9195ac7d8ac9104da61a25c6e.htm)
8. Flash FMS 交互

Flash Media Server ,简称 FMS ,也是一款视频、音频应用服务器。利用 FMS ,可以很轻松的完成视频、音频的录制、点播。也可以利用其作为聊天室的服务器……
这里主要讲述 flash fms 之间的交互,不涉及音、视频应用。

 

环境配置:
下载安装 Flash Media Server3.5
安装路径不能包含中文。在安装时注意记住自己设置的的用户名和密码。安装完后打开 fms 目录下的 tool 文件夹,双击 start.bat 启动服务器,然后打开 Administrator.swf ,输入用户名和密码进入。服务端的 trace 就是在该 swf 中看的。如果改动了服务端文件,要点击右上角 reload 按钮重新加载该服务。 fms 下有个 applications 文件夹,是用来放置服务端文件的,包括你以后录制的视频、音频,都可以在这个文件夹下找到。 applications 的路径也可以另外设置。

 

Flash 客户端通过 NetConnection 类连接 FMS ,可以侦听 NetStatusEvent NET_STATUS 事件来检测连接状态。用 call 方法调用服务端方法,服务端返回值通过在调用 call 方法时指定其 responder ,在其 resultFunction (结果处理函数)中处理。
用法:
var nc:NetConnection = new NetConnection();
nc.call( 服务端方法名: string [,结果 / 错误处理: responder ,传递参数 1 * ,传递参数 2 * ,…] );

 

服务端文件以 *.asc 的形式存在,命名为 main 或与 fms 实例同名,后加 .asc 。当一个客户端试图连接 FMS 服务器时,会触发 FMS application.onConnect 事件, FMS 将自动为客户端分配一个 client
application.onConnect = function(client)
{
在这里设置接受或是拒绝客户端的连接,以及供客户端调用的方法。
}
FMS 可以通过两种方式向客户端发送信息,一是 client.call ,另一是 application.broadcastMsg 。第一种方法只向特定的客户端发送消息,第二种方法称为广播,它向所有连接该 FMS 实例的客户端发送消息,效率更高。
用法:
client.call( 客户端方法名: string [ ,结果处理: responder ,传递参数 1 * ,传递参数 2 * ,… ]);
application.broadcastMsg( 客户端方法名: string [,传递参数 1 * ,传递参数 2 * ,…] );
示例浅析:
客户端:
//定义一个nc用于连接FMS
private var nc:NetConnection;
//定义一个responder用于处理客户端调用服务端方法的结果
private var responder:Responder;

nc = new NetConnection();
responder = new Responder(resultHandler, faultHandler);
这里resultHandler和faultHandler分别是结果处理函数和错误处理函数。
//连接FMS服务器下的fmsConnect实例
nc.connect("rtmp://localhost/fmsConnect");
//侦听连接状态
nc.addEventListener(NetStatusEvent.NET_STATUS, checkConnect);

private function checkConnect(e:NetStatusEvent):void
{
  //e.info.code为nc的连接状态
  trace(e.info.code);
  if (e.info.code == "NetConnection.Connect.Success")
  {
    //如果连接成功,调用FMS服务端的方法fmsFunction
    nc.call("fmsFunction",responder, "tata");
    //指定nc的客户端为本类,FMS才能调用此客户端方法
    nc.client = this;
  }
}

//结果处理(接收参数类型根据服务端返回值的类型而定)
private function resultHandler(str:String):void
{
  trace("返回结果:"+str);
}
  //错误处理
  private function faultHandler(obj:*):void
  {
    for each (var s:String in obj)
    {
      trace(s)
    }
  }
  再写一个方法,供服务端调用,此方法必须是public的
  public function clientFunction(_name:String):void
  {
    trace("FMS回调客户端方法:");
    trace("Hello "+_name);
  }
 
服务端:
FMS 服务器的 applications 文件夹下新建一个文件夹,命名为 fmsConnect ,在 fmsConnect 下新建一个文档,命名为 main.asc
在main.asc中输入:
application.onConnect = function(client)
{
//接受客户端的连接(要拒绝连接的话可以用application.rejectConnection(client) )
    application.acceptConnection(client);
    
    client.fmsFunction = function(_name)
    {
      trace("客户端调用服务器方法:");
      trace("Hello," + _name);
    
      //调用客户端函数的两种方法:
      client.call("clientFunction", null, _name);
      //或是application.broadcastMsg("clientFunction",_name);
    
      //返回_name给客户端
      return _name;
    }
}
 
源代码例子已经打包成附件,欢迎互相学习探讨!