Flex與.NET互操作(十一):FluorineFx.Net的及時(shí)通信應(yīng)用(Remote Procedure Call)(二)
一、客戶端的RPC(客戶端調(diào)用服務(wù)器端)
要想實(shí)現(xiàn)客戶端訪問(wèn)服務(wù)器端的方法,首先得對(duì)ActionScript中的NetConnection比較熟悉,該類提供了一個(gè)示例方法call()專們用來(lái)做RPC訪問(wèn),該方法的定義如下:

比如說(shuō)我們?cè)陂_(kāi)發(fā)一個(gè)及時(shí)應(yīng)用的時(shí)候,所有的客戶端都需要同步服務(wù)器的系統(tǒng)時(shí)間,這個(gè)時(shí)候我們就可以在服務(wù)器端提供一個(gè)返回當(dāng)前系統(tǒng)時(shí)間的方法給客戶端調(diào)用。如下:
public string GetServerTime()
{
return DateTime.Now.ToString();
}
有了這個(gè)方法客戶端就可以通過(guò)NetConnection的call()方法實(shí)行遠(yuǎn)程調(diào)用了,并通過(guò)Responder來(lái)處理調(diào)用的結(jié)果,如果所調(diào)用的服務(wù)器端方法沒(méi)有返回值,則在調(diào)用的時(shí)候可以不使用Responder。如下完整的Flex實(shí)例代碼:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" fontSize="12">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.events.ResultEvent;
private var nc:NetConnection;
private var responder:Responder = new Responder(onResult,onError);
private function connectionServer(event:MouseEvent):void
{
nc = new NetConnection();
nc.connect("rtmp://localhost:1617/RPCDemo","abc","123");
nc.addEventListener(NetStatusEvent.NET_STATUS,onStatusHandler);
nc.client = this;
}
private function onStatusHandler(event:NetStatusEvent):void
{
this.connStatus.text = "連接狀態(tài):" + event.info.code;
if(event.info.code == "NetConnection.Connect.Success")
{
trace("連接服務(wù)器成功");
}
}
/* 調(diào)用服務(wù)器端方法 */
private function onGetServerTime(event:MouseEvent):void
{
nc.call("GetServerTime",responder);
}
/* 處理調(diào)用服務(wù)器端方法成功時(shí)返回的結(jié)果 */
private function onResult(result:String):void
{
this.txtResult.text = "方法GetServerTime返回結(jié)果" + result;
}
/* 處理調(diào)用服務(wù)器端方法時(shí)候時(shí)返回的結(jié)果 */
private function onError(event:Event):void
{
trace("調(diào)用服務(wù)器端方法出錯(cuò)");
}
]]>
</mx:Script>
<mx:Button x="30" y="43" label="連接服務(wù)器" click="connectionServer(event)"/>
<mx:Label x="30" y="75" width="296" id="connStatus"/>
<mx:Button x="30" y="112" label="調(diào)用服務(wù)端方法" click="onGetServerTime(event)"/>
<mx:Label x="30" y="153" id="txtResult" width="296"/>
</mx:Application>
FluorineFx.Net的RPC就這么簡(jiǎn)單,客戶端調(diào)用服務(wù)器端的方法,直接通過(guò)當(dāng)前連接的call()方法調(diào)用,使用Responder來(lái)處理調(diào)用的結(jié)果。
二、服務(wù)器端的RPC(服務(wù)器端調(diào)用客戶端)
客戶端和服務(wù)器端的調(diào)用是可以雙向的,服務(wù)器端也同樣可以調(diào)用客戶端的方法。無(wú)論是客戶端還是服務(wù)器端,相互調(diào)用始終都是離不開(kāi)當(dāng)前的連接對(duì)象。如上面客戶端是通過(guò)當(dāng)前連接的call()方法實(shí)現(xiàn)的調(diào)用服務(wù)器端方法,那么服務(wù)器端調(diào)用客戶端的方法同樣如此,也是通過(guò)當(dāng)前連接對(duì)象來(lái)處理。
FluorineFx中用于連接的接口是IConnection,只要客戶端成功的連接上了服務(wù)器端,那么在服務(wù)器端就會(huì)保存所有連接到服務(wù)器端的連接對(duì)象的各種屬性。實(shí)現(xiàn)調(diào)用客戶端方法的則是IServiceCapableConnection接口,IServiceCapableConnection接口的定義如下所示:
如果要想實(shí)現(xiàn)服務(wù)器端調(diào)用客戶端的方法,則必須使用此接口來(lái)完成,需要將當(dāng)前連接的接口IConnection強(qiáng)制轉(zhuǎn)化為
IServiceCapableConnection接口,然后調(diào)用其invoke()方法來(lái)完成服務(wù)器端對(duì)客戶端方法的調(diào)用。
/// <summary>
/// 調(diào)用客戶端的方法
/// </summary>
/// <param name="connection"></param>
public void InvokeClient()
{
IServiceCapableConnection conn = FluorineContext.Current.Connection as IServiceCapableConnection;
if (connection != null)
{
object[] args = new object[] { GetServerTime() };
conn.Invoke("RecServerMessage", args);
}
}
在服務(wù)器端可以通過(guò)FluorineContext.Current.Connection獲取到當(dāng)前客戶端的連接對(duì)象,然后將其轉(zhuǎn)化為IServiceCapableConnection接口對(duì)象,調(diào)用其Invoke()方法便可實(shí)現(xiàn)調(diào)用客戶端的方法。
這里需要注意一點(diǎn)就是,提供給服務(wù)器端調(diào)用的客戶端方法必須是公共方法(public修飾的方法),否則服務(wù)器端會(huì)報(bào)"Not found method:方法名"的異常。如下代碼塊:
* 接收服務(wù)器端的調(diào)用方法
* */
public function RecServerMessage(message:Object):void
{
Alert.show(message.toString());
}
FluorineFx.Net所提供的上面這兩種功能是非常實(shí)用的,特別是在開(kāi)發(fā)及時(shí)應(yīng)用的時(shí)候,客戶端RPC可以方便是實(shí)現(xiàn)將客戶端是數(shù)據(jù)請(qǐng)求到服務(wù)器端進(jìn)行處理,比如開(kāi)發(fā)網(wǎng)絡(luò)游戲中,游戲客戶端的不同數(shù)據(jù)隨時(shí)都在改變,那么我們就可以使用客戶端RPC來(lái)實(shí)現(xiàn)這一需求。服務(wù)器端RPC 同樣可以應(yīng)用于此,游戲中的數(shù)據(jù)變化了通過(guò)客戶端RPC請(qǐng)求到服務(wù)器端,服務(wù)器端進(jìn)行相與的業(yè)務(wù)計(jì)算和處理之后將客戶端需要的數(shù)據(jù)通過(guò)服務(wù)器端RPC返回到當(dāng)前請(qǐng)求的客戶端。
或許有的朋友會(huì)想或是問(wèn)到,如果我要開(kāi)發(fā)一個(gè)聊天室,要實(shí)現(xiàn)系統(tǒng)廣播消息是不是可以使用這種方式來(lái)實(shí)現(xiàn)。答案是肯定的,系統(tǒng)要廣播消息,可以從服務(wù)器端獲取到所有連接到服務(wù)器端的客戶端,然后循環(huán)的調(diào)用客戶端的方法來(lái)實(shí)現(xiàn)系統(tǒng)廣播消息。關(guān)于如何實(shí)現(xiàn)系統(tǒng)廣播這里我就不作介紹,因?yàn)?FluorineFx.Net為我們提供了更好的方式來(lái)實(shí)現(xiàn)系統(tǒng)廣播。有興趣的朋友請(qǐng)關(guān)注我的后續(xù)文章,在下一篇文章里我將詳細(xì)介紹這方面的知識(shí)點(diǎn)。
相關(guān)文章
基于Socket的網(wǎng)絡(luò)連接 Flex與.NET互操作(一)
Flash/Flex也支持基于Socket的網(wǎng)絡(luò)連接 ,服務(wù)器端可以是C++,VB,C#,Java等任一語(yǔ)言開(kāi)發(fā)。監(jiān)聽(tīng)一個(gè)網(wǎng)絡(luò)端口便可以接收到Flash/Flex開(kāi)發(fā)的客戶端的連接。2009-06-06Flex 非常實(shí)用的學(xué)習(xí)資料整理
對(duì)于學(xué)習(xí)flex 的朋友,絕對(duì)是個(gè)不錯(cuò)的一些資料,大家可以用ctrl+F搜索獲取2009-01-01