利用Flash5的XML能力,用SOAP進(jìn)行通訊,可以創(chuàng)建Flash界面Web應(yīng)用程序。SOAP(Simple Object Access Protocal)是通過網(wǎng)絡(luò)平臺(tái)在不同的系統(tǒng)間交換數(shù)據(jù)的方法。SOAP使用XML文檔,通過類似于HTTP的協(xié)議處理網(wǎng)頁的請(qǐng)求和和回應(yīng)動(dòng)作。
由微軟的.NET和Apache SOAP看來,SOAP是用來在不同的系統(tǒng)間交換數(shù)據(jù)協(xié)議中是最方便的一種。
這篇文章中,你可以看到怎樣建立一個(gè)基于Flash的計(jì)算器,并利用SOAP進(jìn)行遠(yuǎn)程過程調(diào)用(RPC)在服務(wù)器上建立簡單的計(jì)算程序。
要完成這個(gè)例子,你需要安裝了Flash5,微軟的SOAP Toolkit2.0 SP2,Visual Basic,Windows NT/2000 server和IIS。
本程序需要建立服務(wù)器應(yīng)用程序和監(jiān)聽器,用來處理所有收到的SOAP請(qǐng)求。這個(gè)程序使用了微軟的ASP監(jiān)聽器和SOAPCalc ActiveX DLL,這些都可以在微軟的SOAP Tookit中找到。
另外,還需要一個(gè)封裝了SOAP的Flash組件,這個(gè)免費(fèi)的組件可以在http://software.mrev.com/soap.asp下載到。
都準(zhǔn)備好了之后,讓我們開始吧。
第一步:建立ASP監(jiān)聽器
在服務(wù)器端,需要對(duì)進(jìn)入的SOAP請(qǐng)求進(jìn)行操作?梢允褂肁SP文件來處理這些請(qǐng)求。首先,在IIS中建立一個(gè)新的目錄或是虛擬目錄,并命名為SOAPCalc。在這個(gè)目錄中,建立一個(gè)新的ASP文件,并命名為“default.asp”
輸入以下代碼:
<%@language=vbscript%> <% Set CalcSrv = Server.CreateObject("SOAPCalc.CalcSrv") CalcSrv.Process Request, Response %> |
這個(gè)ASP頁面接收從Flash中發(fā)送來的SOAP XML請(qǐng)求,并把Request和Response對(duì)象傳遞給CalcServ組件
圖1 |
CalcSrv從數(shù)據(jù)流中讀入并解析SOAP請(qǐng)求,完成所需要的計(jì)算。并且把ASP的Response對(duì)象通過SOAP送到客戶端。
圖2 |
客戶端的Flash應(yīng)用程序讀取了返回?cái)?shù)據(jù),刷新計(jì)算器的顯示。
第二步:建立服務(wù)器端計(jì)算器組件
下一步,建立服務(wù)器端的用來完成計(jì)算操作的組件。打開Visual Basic 6,建立一個(gè)新的ActiveX DLL工程。
這個(gè)組件和SOAP Toolkit中的“Using a Low Level API for SOAP Messages”這個(gè)例子程序是相同的,但是我們把工程的名字改成了SOAPCalc。如果你沒有安裝Visual Basic,也可以直接下載編譯過的CalcServ安裝程序(見參考)。安裝程序?qū)?fù)制并注冊(cè)所有需要的文件。本文后面的zip包中有這個(gè)例子的VB代碼,以及編譯好的DLL文件。
這個(gè)演示程序通過SOAP reader對(duì)象讀取進(jìn)入的請(qǐng)求。然后,它將檢查請(qǐng)求中的SOAP封裝是否包含叫做<Add><Subtract>, <Multiply> 或 <Divide>的節(jié)點(diǎn),以及兩個(gè)子節(jié)點(diǎn)<A>和<B>。如果找到了,它將處理請(qǐng)求,并且通過serializer返回SOAP消息和ASP的Response對(duì)象。
因?yàn)镕lash的XML解析器不能處理XML標(biāo)記的名稱空間,所以,需要使用單一的結(jié)構(gòu)。
一般的SOAP主體是這樣的:
<SOAPSDK1:AddResponse xmlns:SOAPSDK1="uri:Calc"> <SOAPSDK1:Answer>12</SOAPSDK1:Answer> </SOAPSDK1:Response> |
但是,由于前述的理由,我們不能直接使用這樣的結(jié)構(gòu)。而應(yīng)該用下面這樣Flash支持的語法形式。這種形式包容了同樣的數(shù)據(jù),只是沒有SOAPSDK的名字空間和標(biāo)記前綴而已。
<AddResponse> 。糀nswer>12</Answer> </AddResponse> |
做這些改變,首先應(yīng)該從這個(gè)模塊的代碼前端的聲明部分去掉下面這行:
Const CALC_NS = "uri:Calc" |
然后,要告訴SOAP Serializer不使用特定的名字空間。把這段代碼:
... Serializer.startBody Serializer.startElement MethodName & "Response", CALC_NS Serializer.startElement "Answer", CALC_NS ... |
修改成這樣:
... Serializer.startBody Serializer.startElement MethodName & "Response" Serializer.startElement "Answer" ... |
好了,現(xiàn)在可以編譯DLL了。然后IIS服務(wù)器上注冊(cè)它。(在控制臺(tái)或是run對(duì)話框中使用regsvr32.exe命令,形式是:regsvr32 DLL所在路徑\DLL文件名)
第三步:建立Flash界面
前面的兩個(gè)步驟完成后,就我們繼續(xù)建立客戶端的Flash界面。
首先,在Flash中建立一個(gè)簡單的計(jì)算器界面。這個(gè)界面和普通的數(shù)字計(jì)算器很相似--用戶在鍵盤上輸入數(shù)值和計(jì)算方法,計(jì)算器顯示出計(jì)算結(jié)果。為了能夠進(jìn)行計(jì)算,在Flash中需要有一些全局變量來存放數(shù)值和計(jì)算方法。當(dāng)用戶點(diǎn)擊計(jì)算器的按鈕時(shí),更新這些變量的值。我們用三個(gè)root-level變量存放了這些數(shù)據(jù):
_root.calcValue 存放計(jì)算器顯示的數(shù)值
_root.operator 存放選擇了的計(jì)算方法
_root.lastValue 存放上一次運(yùn)算的結(jié)果
然后需要建立各種與用戶交互的按鈕,比如0~9的數(shù)字,各種運(yùn)算符,小數(shù)點(diǎn),等號(hào)等等。除此之外,還需要建立一個(gè)文本框,以便顯示計(jì)算結(jié)果。在Flash中,通過動(dòng)態(tài)文本(Dynamic Text)把變量綁定到文本框上,這個(gè)文本框中將顯示出變量的值,并隨變量的變化而刷新。(方法是:從text options面版中選擇Dynamic Text,設(shè)置bind variable為 _root.calcValue。)
下一步,為每個(gè)按鈕建立相應(yīng)的Action:當(dāng)數(shù)字按鈕被按下的時(shí)候,更新變量 _root.calcValue 的值,當(dāng)運(yùn)算符按鈕被按下時(shí),設(shè)置變量_root.operator的值。這個(gè)值要和服務(wù)器端的SOAPCalc 組件所需要的值保持一致。(本例中是"Add", "Subtract", Multiply", 或 "Divide")同樣在這個(gè)Action中,添加代碼用來把當(dāng)前的計(jì)算結(jié)果保存到變量_root.lastValue中。運(yùn)算符按鈕的Action中應(yīng)該有這樣的代碼:
on (release) { // operator應(yīng)該是 "Add", "Subtract", Multiply", 或 "Divide" _root.operator = "Add"; _root.lastValue = _root.calcValue; ... } |
下面,添加"="按鈕的Action,當(dāng)用戶按下這個(gè)按鈕的時(shí)候,將調(diào)用函數(shù)發(fā)送SOAP消息,進(jìn)行計(jì)算:
on (release) { _root.calculate(_root.operator, _root.lastValue, _root.calcValue); } |
在Flash影片的root level中的新層中,建立一個(gè)所有函數(shù)都將用到的Action。在這個(gè)Action中,建立一個(gè)函數(shù)calculate()處理SOAP請(qǐng)求和回應(yīng)。函數(shù)calculate()的作用是向服務(wù)器發(fā)送運(yùn)算所需要的兩個(gè)數(shù)和運(yùn)算符。
其形式是:
function calculate(operator, a, b) { ... } |
具體的代碼將在下面的部分繼續(xù)填充。
第四步:實(shí)現(xiàn)SOAP消息
其實(shí)這樣功能的計(jì)算器使用Flash集成的腳本語言ActionScript就可以輕松完成,但是我們這里演示的是SOAP計(jì)算器,所以需要利用服務(wù)器完成所有的計(jì)算請(qǐng)求。Flash5能夠發(fā)送和接受XML文檔,而SOAP消息也是普通的XML文檔,所以我們可以使用Flash集成的XML對(duì)象來建立和解析SOAP消息。
為了使建立Flash/SOAP應(yīng)用程序的過程更為簡單,你可以下載Media Revolution所開發(fā)的Flash SOAP組件。它是免費(fèi)的。這個(gè)組件通過封裝XML操作而簡化了在Flash中發(fā)送和接受SOAP消息的操作?梢詮膆ttp://software.mrev.com/soap.asp下載這個(gè)組件。使用方法是把它復(fù)制到Flash影片所在目錄,在root level加入一個(gè)名為SOAP的影片夾子,并加入如下代碼:
loadMovie ("SOAP.swf", "_root.SOAP"); |
在函數(shù)calculate()中使用這個(gè)SOAP對(duì)象。首先,創(chuàng)建一個(gè)新的SOAP對(duì)象。注意名稱"SOAP"要和上一步加入的SOAP組件名稱相同。
為這個(gè)對(duì)象的onLoad屬性分配一個(gè)函數(shù)名。這個(gè)函數(shù)在SOAP對(duì)象接受或處理SOAP回應(yīng)時(shí)運(yùn)行。(函數(shù)displayCalcResult將在后面定義)。
代碼如下:
function calculate (operator, a, b) { ... var SOAPCalc = new SOAP.SOAP(); SOAPCalc.onLoad = displayCalcResult; ... } |
然后,使用內(nèi)建的SOAP方法createMethod() 和 addParameter() 定義遠(yuǎn)端過程調(diào)用的類型。SOAP對(duì)象假定服務(wù)器應(yīng)用程序期望的節(jié)點(diǎn)和調(diào)用的方法同名。并且返回一個(gè)名稱為[方法名]Response的節(jié)點(diǎn)。 (比如 AddResponse)。
代碼如下:
function calculate (operator, a, b) { ... SOAPCalc.createMethod(operator); SOAPCalc.addParameter("A", a); SOAPCalc.addParameter("B", b); ... } |
最后,使用SOAP對(duì)象的方法send(),把請(qǐng)求發(fā)送到前面建立的SOAP監(jiān)聽器的地址上。
function calculate (operator, a, b) { ... SOAPCalc.send ("http://localhost/SOAPCalc/default.asp"); ... } |
注:因?yàn)榘踩珕栴},F(xiàn)lash播放器限制SOAP請(qǐng)求和影片在一個(gè)子域中。Macromedia將發(fā)布一個(gè)修正版的播放器,以便解決這一問題。
當(dāng)SOAP對(duì)象收到和解析服務(wù)器發(fā)回的回應(yīng),onLoad事件將被觸發(fā)。通過前面分配給onLoad屬性的函數(shù),可以很容易的存取服務(wù)器的回應(yīng)信息。比如:
function displayCalcResult () { _root.calcValue = this.Response.Answer; } |
SOAP Response對(duì)象中的[函數(shù)名]Response.Answer節(jié)點(diǎn)中存放的就是計(jì)算結(jié)果。
回應(yīng)的SOAP消息如下所示:
<SOAP-ENV:Envelope xmlns: SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"> <SOAP-ENV:Body> 。糀ddResponse> 。糀nswer>10</Answer> 。/AddResponse> 。/SOAP-ENV:Body> </SOAP-ENV:Envelope> |
上面的displayCalcResult()遠(yuǎn)程操作返回的值存放在root-level的變量 _root.calcValue中,這樣動(dòng)態(tài)文本框?qū)⒆詣?dòng)顯示其值。
這些都做好以后,你就擁有了一個(gè)Flash SOAP計(jì)算器了。完整的演示可參見:http://software.mrev.com/demo/soap
關(guān)于錯(cuò)誤處理,請(qǐng)解析<Fault>節(jié)點(diǎn)的子節(jié)點(diǎn)<faultcode>和其他節(jié)點(diǎn),它們包含了錯(cuò)誤信息:
<?xml version="1.0"?> <SOAP-ENV:Envelope> 。糞OAP-ENV:Body> 。糞OAP-ENV:Fault> 。糵aultcode>Server</faultcode> 。糵aultstring> Parameter missing: B 。/faultstring> </SOAP-ENV:Fault> 。/SOAP-ENV:Body> </SOAP-ENV:Envelope> |
通過Flash使用SOAP傳遞信息,把用戶界面和數(shù)據(jù)分離,是一個(gè)不錯(cuò)的主意。這樣客戶端可以得到比以往的Web界面更豐富的多媒體界面。通過在Flash函數(shù)內(nèi)封裝SOAP請(qǐng)求和SOAP組件,大大降低了開發(fā)難度,甚至可以讓對(duì)XML和SOAP不很熟悉的Flash開發(fā)人員輕松的應(yīng)用。