FLASH通訊小結

<ps:本資料由小師妹tata整理!>
 
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. FlashJS交互

       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方式傳輸的,URLRequestmethod屬性指定數據的傳輸方式,URLRequestMethod.GETHTTP GET,而URLRequestMethod.POSTHTTP POSTURLRequestdata屬性設置要發送的數據,如果是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);
}
 
服務端:
<?php
         $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工具箱。可用於PHPFlashFlex之間利用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輸入以下代碼:
<?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. FlashFMS交互

Flash Media Server,簡稱FMS,也是一款視頻、音頻應用服務器。利用FMS,可以很輕鬆的完成視頻、音頻的錄製、點播。也可以利用其作爲聊天室的服務器……
這裏主要講述flashfms之間的交互,不涉及音、視頻應用。

 

環境配置:
下載安裝Flash Media Server3.5
安裝路徑不能包含中文。在安裝時注意記住自己設置的的用戶名和密碼。安裝完後打開fms目錄下的tool文件夾,雙擊start.bat啓動服務器,然後打開Administrator.swf,輸入用戶名和密碼進入。服務端的trace就是在該swf中看的。如果改動了服務端文件,要點擊右上角reload按鈕重新加載該服務。fms下有個applications文件夾,是用來放置服務端文件的,包括你以後錄製的視頻、音頻,都可以在這個文件夾下找到。applications的路徑也可以另外設置。

 

Flash客戶端通過NetConnection類連接FMS,可以偵聽NetStatusEventNET_STATUS事件來檢測連接狀態。用call方法調用服務端方法,服務端返回值通過在調用call方法時指定其responder,在其resultFunction(結果處理函數)中處理。
用法:
var nc:NetConnection = new NetConnection();
nc.call(服務端方法名:string[,結果/錯誤處理:responder,傳遞參數1*,傳遞參數2*,…]);

 

服務端文件以*.asc的形式存在,命名爲main或與fms實例同名,後加.asc。當一個客戶端試圖連接FMS服務器時,會觸發FMSapplication.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;
    }
}
 
源代碼例子已經打包成附件,歡迎互相學習探討!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章