本文介绍ESFramework 开发手册(00) -- 概述一文中提到的四大武器的第一个:发送和处理自定义信息。
使用通信框架最基础的需求就是收发信息,ESFramework底层已经为我们封装好了所有与信息收发相关的操作,我们只要调用ESPlus.Application.CustomizeInfo命名空间下的相关组件的API来发送信息,以及实现对应的处理器接口来处理收到的信息就可以了。
客户端可以发送信息给服务端,也可以发送信息给其他在线用户。
客户端通过ESPlus.Application.CustomizeInfo.Passive.ICustomizeOutter接口提供的方法来发送信息。
我们可以从ESPlus.Rapid.IRapidPassiveEngine暴露的CustomizeOutter属性来获取ICustomizeOutter引用。
发送信息有几种方式:
调用Send方法进行普通发送,即将信息写入网络流后就立即返回。
调用SendCertainly方法发送信息时会启用ACK机制,即将信息发送出去后,调用并不返回,而是要等到接收方的ACK后,才返回。ACK机制是由ESPlus底层实现的,我们直接使用,不需要做任何额外的其它工作。关于带ACK机制的信息发送的更多内容可以参见自定义信息的ACK机制。
调用Query方法可以发送请求信息,并返回接收方处理请求后的应答信息。就像方法调用一样 - - 使用参数调用方法并返回结果。从Query方法的重载看到,信息同步调用的对象既可以是服务端、也可以是另外一个在线客户端。关于信息同步调用的更多内容可以参见消息同步调用。
调用SendByP2PChannel方法可以明确指定使用P2P通道发送进行发送,这是一种普通发送。如果与接收者之间的P2P通道不存在,则由ActionTypeOnNoP2PChannel参数指示如何动作:使用服务器转发、或者丢弃信息。关于P2P通道的更多内容可看见后面的P2P通道章节。
对于某些类型的P2P信息,我们可能想在服务端监控它,如果这些信息还是经过P2P通道发送的话,那么服务端将捕获不到这些信息。TransferByServer方法用于解决这一问题。如果调用TransferByServer方法发送信息,那么即使有可靠的P2P通道存在,信息仍然会经过服务器中转。
调用BroadcastInGroup方法可以将信息发送给目标组内的在线用户或当前服务器上的所有在线用户。
服务端可以通过ESPlus.Application.CustomizeInfo.Server.ICustomizeController接口向客户端发送信息和广播、以及同步调用客户端。
我们可以从ESPlus.Rapid.IRapidServerEngine暴露的CustomizeController属性来获取ICustomizeController引用。
各个方法含义几乎与客户端是一致的,但是,对于普通发送和广播,服务端可以选择是采用同步发送(Send)还是异步发送(Post)。对于同时要给众多在线用户发送信息时(比如广播),一般采用Post方式,这样可以避免因为某些用户的网路延迟而延迟对后续用户的信息发送。
ICustomizeController接口还暴露了两个事件,我们可以通过预定InformationReceived事件来监控所有来自客户端的自定义信息;通过预定TransmitFailed事件来监控那些转发失败的信息。
SendCertainlyToLocalClient方法和QueryLocalClient方法的名称都以LocalClient结尾,其在ESPlatform群集平台中就会显示其特别的含义 - - 这两个方法只能针对连接到当前服务端的客户端进行调用。而其它的几个方法,则是可以将信息发送给任何在线用户的,即使该用户位于群集中的其它服务器上。
客户端可以收到来自其它客户端或服务端的信息、广播、以及同步调用。那么,我们在客户端如何来处理这些信息了?只要实现ESPlus.Application.CustomizeInfo.Passive.ICustomizeHandler接口即可。
(1)凡是以FromServer结尾的方法,都表示被处理的信息是来自服务端的;否则,表示被处理的信息是由其它在线客户端发出的。
(2)ICustomizeHandler接口的所有方法都是在后台线程中被调用的,所以如果这些方法的实现中涉及到了操作UI,一定要将调用转发到UI线程。
我们可以将ICustomizeHandler实现类的实例传递给ESPlus.Rapid.IRapidPassiveEngine的Initialize方法以挂接到框架。
服务端只要实现ESPlus.Application.CustomizeInfo.Server.ICustomizeHandler接口就可以处理来自客户端的信息(转发的信息除外)。
我们可以将服务端ICustomizeHandler实现类的实例传递给ESPlus.Rapid.IRapidServerEngine的Initialize方法以挂接到框架。
上述的四个接口中有两个是用于发送信息,另外两个是用于处理信息。那么,用哪个方法发出的信息是由处理器的哪个对应的方法来处理的了?我们这里用箭头图示把它们匹配起来。
我们看到客户端和服务端的ICustomizeHandler都是从IBusinessHandler接口继承的,包括还有一些后面即将介绍的处理器接口(命名以“Handler”结尾的)都是从IBusinessHandler继承的,IBusinessHandler即业务处理器,表示其用于处理我们应用系统的具体业务逻辑。
(1)业务处理器将在后台线程中被调用,所以,实现业务处理器的方法中如果涉及到了UI操作,则必须将调用转发到UI线程。
(2)业务处理器的方法必须尽可能快地返回,否则,将不能及时地处理后续的消息。如果某个业务处理方法非常耗时,可以考虑使用异步方式。
最后,大家可以查看demo的源码,并运行demo,来了解信息发送和处理的流程。谢谢。
关于ESFramework的任何问题,欢迎联系我们: