在做FMS開發中,flash客戶端與FMS服務器通信交互數據等是常見的,比如flash客戶端需要一播放一個視頻,需要獲得FMS發向flash端的一條消息等。那麼我們要怎麼才能實現flash客戶端與FMS服務器建立可交互的連接、通信呢?
本文將以flash客戶端於FMS服務器通信爲核心,以經典的"Hello World"示例詳細介紹flash客戶端於FMS服務器通信的實現。要實現兩端通信,在客戶端和服務器端都需要編碼,一邊發起通信請求和接收通信響應信息(flash客戶端),一端則提供接收請求進行業務處理等(FMS服務器端)。
首先從flash客戶端入手,本文的實例非常簡單,要實現的功能就是flash客戶端向FMS服務器端發起請求,調用FMS服務器上的一個方法,然後將FMS服務器上的方法返回值輸出到控制檯。
flash端的開發可以有兩種方式實現:Flash和Flex。本文會將這兩種方式的實現都給出實例。首先看看Flash裏的實現。
啓動Flash CS開發環境,新建立ActionScript 3.0的Flash文件,如下圖:
然後在上面新建立的ActionScript 3.0的Flash文件上,按F9進入動作面板(輸入程序代碼的地方,當然也可以將代碼封裝到單獨的類文件裏),如下圖:
上圖中已經將通過Flash開發連接到FMS服務器的代碼全部貼出,代碼很簡單。NetConnection這個類在 Flash Player 和 Flash Media Server 應用程序之間或者 Flash Player 和運行 Flash Remoting 的應用程序服務器之間創建雙向連接。
通過NetConnection建立於FMS服務器的連接,然後使用NetConnection類的公共方法connect()通過RTMP協議連接到指定的FMS服務器上指定的應用,如上圖示爲連接的FMS服務器上名爲的“HelloWorld”的這個應用。如果對NetConnection還不熟悉的朋友請先閱讀下我的這系列文章的第一篇:《FMS3系列(一):第一個FMS程序,連接到FMS服務器(Flash/Flex兩種實現) 》,隨後通過調用call()方法調用FMS服務器上的方法,這裏通過調用服務器上提供的sayHelloWorld()方法。
Responder 類提供了一個對象,該對象在 NetConnection.call() 中使用以處理來自與特定操作成功或失敗相關的服務器的返回值。詳細見構造Responder對象的時候構造方法的參數,一個方法處理操作成功的邏輯,一個方法處理操作失敗的邏輯。
OK,完成了上面的flash客戶端的開發現在就只差FMS服務器端的開發了,FMS服務器理需要有一個通信文件來負責於flash客戶端的連接交互,通常情況下就是建立一個main.asc的通信文件。本文中的通信文件的程序代碼非常簡單,就是接受客戶端的連接,然後提供一個客戶端調用的方法。完整代碼入下:
2 {
3 client.sayHelloWorld=function(str)
4 {
5 return "I can say:Hello "+ str;
6 }
7 this.acceptConnection(client);
8 }
通過上面的客戶端和FMS服務器的開發,現在這樣可以按Ctrl+Enter測試了,看看我們的flash小程序是否能夠成功的連接到FMS服務器上指定的HelloWorld,併成功調用服務器端指定的方法呢?打開FMS管理控制檯可以看到如下截圖效果。OK,我們的小程序已經成功的連接到了FMS服務器上指定的應用(HelloWorld):
下面是測試輸出結果截圖:
上面的實現是直接將代碼寫在Flash中,我們也可以將代碼提取出來形成ActionScript文件(類),只要該類文件繼承於顯示對象,通過Flash CS3的新特性設置舞臺文檔類就可以調用了,下面是提取爲ActionScript類的編程實現:
2 {
3 import flash.net.*;
4 import flash.events.*;
5 import flash.display.*;
6
7 public class ClientCallServer extends Sprite
8 {
9 private var nc:NetConnection;
10 private var rs:Responder;
11 public function ClientCallServer():void
12 {
13 nc=new NetConnection();
14 rs=new Responder(onSuccess,onFailed);
15 nc.connect("rtmp://localhost/HelloWorld");
16 nc.client=this;
17 nc.call("sayHelloWorld",rs,"World");
18 }
19
20 private function onSuccess(rs:Object):void
21 {
22 trace(rs.toString());
23 }
24
25 private function onFailed(rs:Object):void
26 {
27 trace(rs.description());
28 }
29 }
30 }
或許有的朋友已經習慣了使用Flex開發,喜歡用拖拽控件的方式來完成一些常用的功能,其實在Flex下開發和Flash差別不是很大,其實在編碼層次上是沒什麼區別的,不同的只是界面的呈現方式不一樣。
2 private var fmsServer:String="rtmp://localhost/HelloWorld";
3 private var rs:Responder;
4
5 private function initApp():void
6 {
7 nc = new NetConnection();
8 nc.connect(fmsServer);
9 nc.client=this;
10 }
在Flex下開發,建立好mxml後可以直接在其內部的<mx:Script>組件裏編寫ActionScript代碼,如上定義了連接FMS服務器的NetConnection類的實例等。還定義了一個在Flex應用初始化的使用調用的方法initApp(),用來 完成flash客戶端與FMS服務器的連接。
2 {
3 rs = new Responder(onSuccess,onFailed);
4 nc.call("sayHelloWorld",rs,"World");
5 nc.addEventListener(NetStatusEvent.NET_STATUS,onStatus);
6 nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR,onAsyncHandler);
7 }
同Flash中開發一樣,給Responder指定了成功和失敗後的處理函數,詳細如下:
* 通信成功並返回結果時被調度
*/
private function onSuccess(result:Object):void
{
Alert.show(result.toString(),"調用結果");
}
/**
* 通信失敗並返回結果時被調度
*/
private function onFailed(result:Object):void
{
Alert.show(result.description);
Alert.show(result.code);
}
如上就完成了Flex中調用FMS服務器並調用FMS上所提供的方法,服務器端的程序和前面 Flash中的一樣。到此我們只需要調用onClick()方法就可以測試了,通過一個按鈕組件來調用,如下:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 1<?xml version="1.0" encoding="utf-8"?>
2<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" fontSize="12"
3 creationComplete="initApp()">
4 <mx:Script>
5 <![CDATA[
6 import mx.controls.Alert;
7 private var nc:NetConnection;
8 private var fmsServer:String="rtmp://localhost/HelloWorld";
9 private var rs:Responder;
10
11 private function initApp():void
12 {
13 nc = new NetConnection();
14 nc.connect(fmsServer);
15 nc.client=this;
16 }
17
18 private function onClick():void
19 {
20 rs = new Responder(onSuccess,onFailed);
21 nc.call("sayHelloWorld",rs,"World");
22 nc.addEventListener(NetStatusEvent.NET_STATUS,onStatus);
23 nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR,onAsyncHandler);
24 }
25
26 private function onStatus(evt:NetStatusEvent):void
27 {
28 Alert.show(evt.info.code);
29 }
30
31 public function onAsyncHandler(evt:AsyncErrorEvent):void
32 {
33
34 }
35
36 /**//**
37 * 通信成功並返回結果時被調度
38 */
39 private function onSuccess(result:Object):void
40 {
41 Alert.show(result.toString(),"調用結果");
42 }
43
44 /**//**
45 * 通信失敗並返回結果時被調度
46 */
47 private function onFailed(result:Object):void
48 {
49 Alert.show(result.description);
50 Alert.show(result.code);
51 }
52
53 private function onBWDone(rs:Object):void
54 {}
55 ]]>
56
57 </mx:Script>
58 <mx:Button x="91" y="219" label="Call" click="onClick()"/>
59</mx:Application>
60
61
在平時的開發當中,要與FMS服務器創建可交互的連接有很多種方式,本文只是簡單的介紹了最基本的一種調用,希望本文對想學FMS開發的朋友有所幫助。