FCS閱讀筆記17 應用程序設計和開發

FCS閱讀筆記17 應用程序設計和開發

這篇內容主要講述在FCS應用程序開發過程的一些建議和技巧,包含有服務器兼容性方面的建議、相互依賴關係、多文件管理、帶寬管理、雙字節支持、卸載和重載應用程序和動態訪問控制等~

一、服務器兼容性方面的建議
使用小寫方式命名你的目錄和文件名
Macromedia 推薦你使用小寫字母命名FlashCom開發項目中的目錄和文件,以便更好的工作在不同的服務器之間。
使用相對路徑或絕對路徑連接服務器
在Fcs開發中NetConnect.connect命令可以使用絕對和相對路徑來連接指定的應用程序,如果你的swf文件和FlashCom服務器運行在同一臺機器,你可以使用相對路徑rtmp:/appName/instanceName 來代替
rtmp://server.domain.com/appName/instanceName
如果你的開發你的應用程序在一臺開發服務器,並且沒有使用相對路徑在swf文件中,那麼移動你的swf文件到產品服務器會帶來一些額外的工作,因爲你不得不更改每一個NetConnect.connect語句中url參數。
如果你的swf文件不會和flashCom服務器在同一臺機器,那麼必須加上絕對路徑,(作者注:當然可以通過變量的方法來設置)

二、相互依賴關係
因爲客戶端和服務器端的ActionScript腳本代碼都是應用程序的一部分,他們必須協調工作,並且相互依賴。一個最典型的例子就是在客戶端和服務器端之間使用call命令,因爲調用的方法可能是客戶端或者服務器端自定義的。下面有個例子可以說明:

01 : // 客戶端fla文件的 ActionScript 代碼
02 : my_nc = new NetConnection();
03 : my_nc.someClientMethod = function()
04 : {
05 : //在這裏 添加你的處理代碼
06 : }
07 : my_nc.connect(“rtmp://hostname:port/appname”);
08 :
09 : // 服務器端的main.asc中的 ActionScript 代碼
10 : clientObj.call("someClientMethod");

在服務器端clientObj.call方法傳遞的參數必須是在客戶端已經定義好的NetConnect對象方法,這是因爲任何客戶端的需要被服務器調用的方法必須通過NetConnect對象連接到服務器纔可以。
相反,你在客戶端調用服務器端的方法
01 : // 客戶端代碼
02 : NetConnection.call("someServerMethod");
03 :
04 : // 服務器端代碼
05 : client.prototype.someServerMethod = function()
06 : {
07 : // 這裏是處理代碼
08 : }
09 : // 或者使用下面的調用方式也是有效的
10 : onConnect(newClient)
11 : {
12 : newClient.someServerMethod = function()
13 : {
14 : // code
15 : }
16 : }

在這種情況下,NetConnect.connect方法的參數必須是服務器端(一般是main.asc)已經定義好的方法,這是因爲任何服務器端需要被客戶端調用的方法必須是服務器端的Client對象的方法。

三、使用多文件管理
當你的應用程序日益複雜的時候,不要企圖通過一個單一的腳本來完成所有的事情。把你的函數分成不同的文件,每個提供一定的功能集合。如果你使用多個文件,還可以使用包含的方式來優化性能,使得同一段代碼不需要被執行多次。
客戶端
例如,在客戶端,如果你想把my_file.as文件能夠被應用程序中的其它文件調用,只需要在my_file.as文件開頭寫上下面的代碼:
1 : if (_root._my_file_as == null) {
2 : _root._my_file_as = true;
3 : // All the code for myfile.as goes here
4 : }

然後,在其它文件中,包含下面代碼:
#include "my_file.as";
注意:include指令在編譯時候被執行,而不是運行的時候執行。
服務器端
服務器端的方式有些區別,因爲在服務器端的ActionScript不支持全局對象。例如,你要包含一個my_flie.asc文件,在該文件開頭依然包含下面這段代碼:
1 : if (_my_file_asc == null) {
2 : _my_file_asc = true;
3 : // All the code for myfile.asc goes here
4 : }
區別就在於其它文件包含該文件的時候不使用#include指令,而是使用load指令
load("my_file.asc");

四、使用唯一的實體命名
通常的開發環境是多個用戶同時連接到同一臺服務器,爲了避免數據流衝突或共享對象被覆蓋,可以在NetConnect.connect命令中使用唯一的實體名稱。
如果你想要使用NetConnect 調試工具,你必須在客戶端代碼的第一行包含NetDebug.as文件,(FlashCom1.5版本並沒有包含NetDebug.as文件,你可以在這裏下載)NetDebug.as文件的使用方法不在本文的說明範疇,留待以後再表。

五、強制顯示Flash設置面板
當一個應用程序企圖訪問用戶的攝像機或者麥克風,以及要在本地存儲數據的時候,flash 會顯示設置對話框來得到允許。用戶也可以點擊鼠標右鍵來打開設置面板。如果要強制顯示設置面板,可以使用下面的代碼:
// 不帶參數表示打開用戶上次瀏覽的設置面板
1 : System.ShowSettings();
2 : // 打開保密性設置面板
3 : System.ShowSettings(0);
4 : // 打開本地存儲設置面板
5 : System.ShowSettings(1);
6 : // 打開麥克風設置面板
7 : System.ShowSettings(2);
8 : // 打開照相機設置面板
9 : System.ShowSettings(3);

例如,如果你的應用程序需要使用攝像頭,你可能需要提示用戶在彈出的保密性設置面板中選擇允許。就必須使用
System.showSettings(0)

六、帶寬管理
你可以通過計算近似的帶寬承受度來控制服務器發送到每個客戶端的數據量。有很多種方法可以做到,一種方法是配置FlashCom server的config.xml文件;另一種方法是使用NetStream.receiveVideo 方法來指定傳輸速率;第三種方法是通過設置客戶端Camera.Quality屬性和服務器端的Client.setBandwidthLimit方法。下面會詳細講述第三種方法。
Fcs自帶的doc_bandwidth示例程序演示如何讓用戶選擇不同的帶寬設置。選擇不同的帶寬設置後,客戶端的麥克風和攝像頭設置也會根據用戶的選擇更新,服務器端的帶寬限制也會更新。
客戶端的ActionScript提供了一個用戶界面讓用戶選擇三種不同的帶寬設置:Modem、DSL和LAN。當用戶改變了帶寬限制後,攝像頭和麥克風設置也會更新,還有一個不引人注意的地方,就是updateBandwidth方法也會根據設置的選擇改變屏幕的尺寸。
01 : _root.Modem_btn.onPress = function() {
02 : // Call updateBandwidth to change
03 : // camera and mic settings and inform
04 : // the server
05 : _root.updateBandwidth(1);
06 : }
07 : _root.DSL_btn.onPress = function() {
08 : _root.updateBandwidth(2);
09 : }
10 : _root.LAN_btn.onPress = function() {
11 : _root.updateBandwidth(3);
12 : }

在fla文件的第一幀,你可以找到下面一段代碼,用來初始化攝像頭和麥克風,以及從服務器播放串流和根據用戶的選擇更新攝像頭、麥克風的設置。
01 : #include "NetDebug.as"
02 : stop();
03 : // Initialize movie by getting a camera and microphone, and
04 : // Configure the initial camera and microphone settings
05 : client_cam = Camera.get();
06 : client_cam.setMode(150,120,5);
07 : client_cam.setQuality(0, 90);
08 : client_mic = Microphone.get();
09 : client_mic.setRate(22);
10 : // Get the stream to publish and play
11 : function getPlayStream() {
12 : // Get new net connection
13 : client_nc = new NetConnection();
14 : // Handle status message
15 : client_nc.onStatus = function(info) {
16 : trace("Level: " + info.level + newline + "Code: " + info.code);
17 : }
18 : client_nc.connect("rtmp:/doc_bandwidth/room_01");
19 : // Create a stream to which to publish
20 : out_ns = new NetStream(client_nc);
21 : out_ns.attachVideo(client_cam);
22 : out_ns.attachAudio(client_mic);
23 : out_ns.publish("myAV");
24 : Chapter 5 70
25 : // Create a stream to receive the published data
26 : in_ns = new NetStream(client_nc);
27 : Output_mc.fromSrvr.attachVideo(in_ns);
28 : Output_mc.fromSrvr.attachAudio(in_ns);
29 : in_ns.play("myAV");
30 : }
31 : // Called from the bandwidth buttons
32 : function updateBandwidth(b) {
33 : // Respond to a change in the bandwidth
34 : // If "Modem" was selected
35 : if ( b == 1 ) {
36 : client_cam.setMode(160,120,2);
37 : client_cam.setQuality(0, 75);
38 : client_cam.setKeyFrameInterval(3);
39 : client_mic.setRate(5);
40 : // For demonstration purposes, change size of screen
41 : Output_mc._height = 100;
42 : Output_mc._width = 150;
43 : // If "DSL" was selected
44 : } else if ( b == 2 ) {
45 : client_cam.setMode(160,120,5);
46 : client_cam.setQuality(0, 85);
47 : cam.setKeyFrameInterval(5);
48 : client_mic.setRate(11);
49 : // For demonstration purposes, change size of screen
50 : Output_mc._height = 130;
51 : Output_mc._width = 175;
52 : // If "LAN" was selected
53 : } else /*if ( b == 3 )*/ {
54 : client_cam = Camera.get();
55 : client_cam.setMode(160,120,15);
56 : client_cam.setQuality(0, 90);
57 : client_cam.setKeyFrameInterval(10);
58 : client_mic.setRate(22);
59 : // For demonstration purposes, change size of screen
60 : Output_mc._height = 150;
61 : Output_mc._width = 200;
62 : }
63 : // Call the server function setBandwidth and pass the user’s
64 : // selection, b.
65 : client_nc.call("setBandwidth"
, 0, b);
66 : }
67 : // Get the stream to play
68 : getPlayStream();

在服務端的main.asc文件中,包含了setBandwidth方法,被客戶端調用。
01 : // If server-side code is part of the application,
02 : // it must define an onConnect function that accepts
03 : // the client connection.
04 : application.onConnect = function(client) {
05 : // Establish the connection
06 : application.acceptConnection(client);
07 : }
08 : // Called when user presses a bandwidth choice (Modem=1, DSL=2, LAN=3)
09 : Client.prototype.setBandwidth = function(bw) {
10 : // set the bandwidth for the client
11 : if ( bw == 1 ) {
12 : // modem settings
13 : this.setBandwidthLimit( 35000/8, 22000/8 );
14 : } else if ( bw == 2 ) {
15 : // DSL settings
16 : this.setBandwidthLimit( 800000/8, 100000/8 );
17 : } else {
18 : // LAN settings
19 : this.setBandwidthLimit( 400000, 400000 );
20 : }
21 : }


七、開發雙字節應用程序
如果需要在服務器端的開發環境使用雙字節文字,你的服務器端ActionScript代碼必須使用utf-8編碼。這意味着你必須採用支持UTF-8的編輯器書寫代碼,然後可以用內建的JavaScript方法,例如Date.toLocalString 來轉換成本地編碼。
如果使用雙字節字符作爲方法名稱,必須使用對象數組操作方式而不能用點操作方式。
1 : // 使用雙字節命名的方法格式
2 : obj["方法名稱"] = function(){ }
3 : // 使用單字節命名的方法格式
4 : obj.MethodName = function() { }


八、卸載和重載應用程序
應用程序實體會自動卸載通過垃圾回收機制。當所有的用戶斷開應用程序的連接的時候,垃圾回收會首先運行,然後應用程序會自動卸載。換句話說,並不是所有用戶斷開連接的時候應用程序就馬上卸載。因爲應用程序的啓動通常需要一段時間,所以下一個客戶端的連接並不會佔用啓動的開銷。
默認,垃圾回收每20分鐘發生一次,你可以修改這個值(必須大於0)。
當你對main.asc文件有任何修改的時候,你必須重載應用程序纔可以生效。而這樣就會斷開當前所有用戶的連接。重載應用程序的方法可以通過管理控制檯和應用程序監視器來完成。

九、執行動態訪問控制
服務器端的ActionScript給共享對象和串流對象提供了執行動態訪問控制列表(ACL)的功能機制。默認所有的連接對串流和共享對象有完全訪問權限。你可以控制某個用戶具有創建、讀寫共享對象和串流的權限,每個連接到服務器端的應用程序實體都會有一個服務器端的Client對象參考,並且每一個Client對象都有兩個屬性:readAccess和writeAccess。使用這兩個屬性,就可以設置每個連接的權限。
下面有個示例:
client.readAccess = "appSO/"
client.writeAccess = "appStreams/public/;appSO/public/"
該例子說明了對一個Client對象實體client作了權限控制
如果要對全部Client對象設置權限,可以使用
client.readAccess = "appSO/" ; //所有客戶端都可以訪問appSO目錄
client.writeAccess= "appSO/public/"; //所有連接的客戶端都可以該目錄下創建共享對象或數據流
但是卻無法寫入 appSO/private/ 目錄。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章