聊天系统Demo,增加Silverlight客户端(附源码)-- ESFramework 4.0 快速上手(09)

时间:2024-11-20 12:04:44

ESFramework 4.0 快速上手 -- 入门Demo,一个简单的IM系统(附源码)一文中,我们介绍了使用ESFramework的Rapid引擎开发的winform聊天程序,本文我们将在之前demo的基础上添加使用ESFramework.SL开发的Silverlight客户端。这样一来,不仅Silverlight客户端之间可以相互通信,Silverlight客户端还可以跟winform客户端进行通信。如果不了解在Silverlight中如何使用ESFramework,可以先看看ESFramework 4.0 快速上手 -- 在Silverlight中使用ESFramework

Silverlight客户端同样实现了以下功能并有所增强:

(1)客户端用户上下线时,通知其他在线用户。

(2)当客户端与服务端网络断开时,进行自动重连,当网络恢复后,重连成功。

(3)所有在线用户(包括Winform客户端)之间可以进行文字聊天。

(4)消息同步调用。(演示了三种类型的同步调用)

(5)重登陆模式。当同名的用户登陆时,会把前面的用户挤掉。

一.服务端

服务端直接使用ESFramework 4.0 快速上手 -- 入门Demo,一个简单的IM系统(附源码的实现,并且增加了服务器同步调用客户端的功能 -- 即服务端向某个在线客户端提交请求并返回客户端的回复信息。我们利用了服务端UI的“工具”菜单里面“自定义功能”,当点击这个菜单时,将默认向在线用户列表中的第一个用户发送同步调用请求。如图中第一个在线用户是aa01,那么点击“自定义功能”后,就由aa01来处理服务端的同步调用。

聊天系统Demo,增加Silverlight客户端(附源码)-- ESFramework 4.0 快速上手(09)

服务端同步调用客户端由ICustomizeInfoController.QueryClient()方法来实现。


        /// <summary>
        /// 询问在线客户端,并返回应答信息。如果目标用户不在线,或超时没有应答则将抛出Timeout异常。
        /// </summary>      
        /// <param name="userID">接收并处理服务器询问的目标用户ID</param>
        /// <param name="informationType">自定义请求信息的类型</param>
        /// <param name="info">请求信息</param>
        /// <returns>客户端给出的应答信息</returns>
        byte[] QueryClient(string userID, int informationType, byte[] info);

二.客户端

1.客户端的MainPage类实现了ESFramework.SL.Application.Basic.IBasicBusinessHandler接口,以接收其他用户的上下线通知、被挤掉线通知、心跳超时通知等。

2.客户端的MainPage类还实现了ESFramework.SL.Application.CustomizeInfo.ICustomizeInfoBusinessHandler接口,以处理来自其它用户的聊天消息、来自服务端的同步调用、以及来自其它客户端的P2P同步调用等。

3.客户端的MainPage类还预定并处理了ESFramework.SL.Rapid.IRapidPassiveEngine的TcpPassiveEngine属性的与连接状态变化相关的事件,如连接断开、重连开始、重连成功/失败。

客户端启动登陆后,显示的主界面MainPage如下:

聊天系统Demo,增加Silverlight客户端(附源码)-- ESFramework 4.0 快速上手(09)
  当有其他用户登陆时,会在“在线用户列表”中显示出来,点击选择用户ID,就可以与该用户聊天。UI右边上面是与所选择的用户的聊天历史记录,下面是发送消息的文本框。 从在线用户列表选择要对话的好友,然后在聊天输入框输入文本,最后点击“发送”按钮即可。程序通过ESFramework.SL.Application.CustomizeInfo.ICustomizeInfoOutter的Send方法发送消息给好友。

   void Send(string targetUserID, int informationType, byte[] info);

好友掉线时,好友的名称会从好友列表中消失,如果正在与该好友聊天,则右边的历史记录会清空,“发送”按钮也不再可用。

  如果我们在另一个地方再登陆一个aa01(演示重登陆),程序会先回调ESFramework.SL.Application.Basic.IBasicBusinessHandler的OnBeingPushedOut(),然后再触发TcpPassiveEngine的ConnectionInterrupted事件,通知当前的用户。

 三、同步调用

这个demo里面演示了三种类型的同步调用:客户端与客户端之间的同步调用,客户端同步调用服务端,服务端同步调用客户端。

1.客户端同步调用服务端:这个在前一个Demo中演示过,在Sliverlight客户端中完全使用一样的模式。

2. 服务端同步调用客户端:这个在第一部分已经介绍,而客户端是通过实现ICustomizeInfoBusinessHandler接口的HandleQueryFromServer方法来处理来自服务端的同步调用的:


        /// <summary>
        /// 处理来自服务端的询问信息,并给出应答信息。(即处理服务端ICustomizeInfoController.QueryClient发出的请求)
        /// </summary>    
        /// <param name="informationType">自定义信息类型</param>
        /// <param name="info">二进制信息</param>
        /// <returns>应答信息</returns>
        byte[] HandleQueryFromServer(int informationType, byte[] info);    

3. 客户端同步调用客户端:调用是由ICustomizeInfoOutter接口的CommitP2PRequest方法来发出的,


        /// <summary>
        /// 向在线目标用户提交请求信息,并返回应答信息。如果目标用户不在线,或超时没有应答则将抛出Timeout异常。
        /// </summary>      
        /// <param name="targetUserID">接收并处理请求消息的目标用户ID</param>
        /// <param name="requestInfoType">自定义请求信息的类型</param>
        /// <param name="requestInfo">请求信息</param>
        /// <returns>应答信息</returns>
        byte[] CommitP2PRequest(string targetUserID, int requestInfoType, byte[] requestInfo);

目标客户端收到来自其他用户的同步调用请求后,会由ICustomizeInfoBusinessHandler接口的HandleP2PRequest方法来处理这个请求:

        byte[] HandleP2PRequest(string sourceUserID, int requestInfoType, byte[] requestInfo);

四. 两种类型的客户端公用同一服务端

      基于ESFramework Rapid引擎开发的winform客户端和silverlight客户端可以公用同一个服务端,甚至以后,ESFramework还可能支持基于C++/Flash/Java的客户端。下图是本文的Demo启动后,silverlight客户端和winform客户端用户之前的通信截图。

聊天系统Demo,增加Silverlight客户端(附源码)-- ESFramework 4.0 快速上手(09)

五.Demo源码下载

下载本文的Demo源码。注意,在运行基于Silverlight的客户端程序时,服务器上首先应该起到“Silverlight策略服务器”,可以从ESFramework 4.0 概述文末下载策略服务器。