Flex与.NET互操作(十一):FluorineFx.Net的及时通信应用(Remote Procedure Call)(二)
NET的服务器端同样也可以非常方便的呼叫客户端,调用客户端的方法(比如实现系统广播)。
一、客户端的RPC(客户端调用服务器端)
要想实现客户端访问服务器端的方法,首先得对ActionScript中的NetConnection比较熟悉,该类提供了一个示例方法call()专们用来做RPC访问,该方法的定义如下:
public function call(command:String, responder:Responder, arguments):void
比如说我们在开发一个及时应用的时候,所有的客户端都需要同步服务器的系统时间,这个时候我们就可以在服务器端提供一个返回当前系统时间的方法给客户端调用。如下:
//返回当前系统时间
public string GetServerTime()
{
return DateTime.Now.ToString();
}
有了这个方法客户端就可以通过NetConnection的call()方法实行远程调用了,并通过Responder来处理调用的结果,如果所调用的服务器端方法没有返回值,则在调用的时候可以不使用Responder。如下完整的Flex实例代码:
<?xml version="1.0" encoding="utf-8"?>
<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 = "连接状态:" + event.info.code;
if(event.info.code == "NetConnection.Connect.Success")
{
trace("连接服务器成功");
}
}
/* 调用服务器端方法 */
private function onGetServerTime(event:MouseEvent):void
{
nc.call("GetServerTime",responder);
}
/* 处理调用服务器端方法成功时返回的结果 */
private function onResult(result:String):void
{
this.txtResult.text = "方法GetServerTime返回结果" + result;
}
/* 处理调用服务器端方法时候时返回的结果 */
private function onError(event:Event):void
{
trace("调用服务器端方法出错");
}
]]>
</mx:Script>
<mx:Button x="30" y="43" label="连接服务器" click="connectionServer(event)"/>
<mx:Label x="30" y="75" width="296" id="connStatus"/>
<mx:Button x="30" y="112" label="调用服务端方法" click="onGetServerTime(event)"/>
<mx:Label x="30" y="153" id="txtResult" width="296"/>
</mx:Application>
FluorineFx.Net的RPC就这么简单,客户端调用服务器端的方法,直接通过当前连接的call()方法调用,使用Responder来处理调用的结果。
二、服务器端的RPC(服务器端调用客户端)
客户端和服务器端的调用是可以双向的,服务器端也同样可以调用客户端的方法。无论是客户端还是服务器端,相互调用始终都是离不开当前的连接对象。如上面客户端是通过当前连接的call()方法实现的调用服务器端方法,那么服务器端调用客户端的方法同样如此,也是通过当前连接对象来处理。
FluorineFx中用于连接的接口是IConnection,只要客户端成功的连接上了服务器端,那么在服务器端就会保存所有连接到服务器端的连接对象的各种属性。实现调用客户端方法的则是IServiceCapableConnection接口,IServiceCapableConnection接口的定义如下所示:
如果要想实现服务器端调用客户端的方法,则必须使用此接口来完成,需要将当前连接的接口IConnection强制转化为
IServiceCapableConnection接口,然后调用其invoke()方法来完成服务器端对客户端方法的调用。
/// <summary>
/// 调用客户端的方法
/// </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);
}
}
在服务器端可以通过FluorineContext.Current.Connection获取到当前客户端的连接对象,然后将其转化为IServiceCapableConnection接口对象,调用其Invoke()方法便可实现调用客户端的方法。
这里需要注意一点就是,提供给服务器端调用的客户端方法必须是公共方法(public修饰的方法),否则服务器端会报"Not found method:方法名"的异常。如下代码块:
/**
* 接收服务器端的调用方法
* */
public function RecServerMessage(message:Object):void
{
Alert.show(message.toString());
}
FluorineFx.Net所提供的上面这两种功能是非常实用的,特别是在开发及时应用的时候,客户端RPC可以方便是实现将客户端是数据请求到服务器端进行处理,比如开发网络游戏中,游戏客户端的不同数据随时都在改变,那么我们就可以使用客户端RPC来实现这一需求。服务器端RPC 同样可以应用于此,游戏中的数据变化了通过客户端RPC请求到服务器端,服务器端进行相与的业务计算和处理之后将客户端需要的数据通过服务器端RPC返回到当前请求的客户端。
或许有的朋友会想或是问到,如果我要开发一个聊天室,要实现系统广播消息是不是可以使用这种方式来实现。答案是肯定的,系统要广播消息,可以从服务器端获取到所有连接到服务器端的客户端,然后循环的调用客户端的方法来实现系统广播消息。关于如何实现系统广播这里我就不作介绍,因为 FluorineFx.Net为我们提供了更好的方式来实现系统广播。有兴趣的朋友请关注我的后续文章,在下一篇文章里我将详细介绍这方面的知识点。