博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【转载】ESFramework介绍之(27)-- 支持OverdueMessage (离线消息)
阅读量:5956 次
发布时间:2019-06-19

本文共 4145 字,大约阅读时间需要 13 分钟。

(离线消息)

   (本文适用于ESFramework V0.2+)

     QQ上,你给好友发消息,如果对方不在线,则服务器会把这个消息持久化存起来,等好友下次上线时,再转发给他。像这样的消息在ESFramework中称为OverdueMessage。显然,MSN没有支持OverdueMessage。 当然了,ESFramework中的OverdueMessage不仅仅是文字消息,而是可以为任何类型的消息,比如,音频、视频、文件等等。
    ESFramework中对所有P2P的消息的处理都是由P2PMessageDealer完成的,当P2PMessageDealer转发一个消息时,发现目标用户不在线,就会将这个消息交给一个称为IOverdueMessageHandler的组件处理,IOverdueMessageHandler组件可以持久化存储这个消息,也可以直接将其保存在内存中,具体采用哪种方式,取决于你的应用。
    IOverdueMessageHandler组件有如下职责:
(1)保存(或持久化)存储OverdueMessage
(2)提取指定目标用户的所有OverdueMessage
(3)当OverdueMessage成功发送给目标用户后,改变OverdueMessage的状态或删除这些OverdueMessage。
    基于此,IOverdueMessageHandler接口设计如下:

    public
 
interface
 IOverdueMessageHandler
    {
        
bool
  Enabled{
set
 ;}
        
void
  HandleOverdueP2PMessage(NetMessage revMsg) ; 
        IList PickupOverdueP2PMessage(
string
 destUserID) ; 
//列表中为
NetMessage元素
        
void
  SetOverdueMessageSended(
string
 destUserID) ;
    }

    对应的类图:

    
    IOverdueMessageHandler由应用实现,因为只有你的应用需求才能决定处理OverdueMessage的物理方式。P2PMessageDealer的实现中引入了IOverdueMessageHandler,如下:

            int
 result 
=
 
this
.toClientSender.HookAndSendMessage(reqMsg.Header.DestUserID ,reqMsg) ;
            
if
(result 
!=
 DataSendResult.Succeed) 
//
处理没有发送成功的消息
            {
                
if
(
this
.overdueMessageHandler 
!=
 
null
)
                {
                    
this
.overdueMessageHandler.HandleOverdueP2PMessage(reqMsg) ;
                }
            }      
            
//

    我们需要另外一个组件来负责发送OverdueMessage给目标用户,那就是OverdueMessageSender,它可以让你指定在多久之后发送OverdueMessage给指定的用户,如果没有指定这个时间间隔,就立即发送。

   

ContractedBlock.gif
ExpandedBlockStart.gif
OverdueMessageSender
    public class OverdueMessageSender
    {
        
#region property
        
#region ToClientSender
        
private IToClientSender toClientSender = null ; 
        
public  IToClientSender ToClientSender
        {
            
set
            {
                
this.toClientSender = value ;
            }
        }
        
#endregion
        
#region OverdueMessageHandler
        
private IOverdueMessageHandler overdueMessageHandler = null ; 
        
public  IOverdueMessageHandler OverdueMessageHandler
        {
            
set
            {
                
this.overdueMessageHandler = value ;
            }
        }
        
#endregion    
        
#region SendDelay
        
private int sendDelay = 0 ; //ms 
        public  int SendDelay
        {
            
set
            {
                
this.sendDelay = value ;
            }
        }
        
#endregion
        
#region EsbLogger
        
private IEsbLogger esbLogger = null ; 
        
public  IEsbLogger EsbLogger
        {
            
set
            {
                
this.esbLogger = value ;
            }
        }
        
#endregion        
        
#endregion
        
public OverdueMessageSender()
        {            
        }
        
public void SendOverdueMessage(string userID)
        {
            IList list 
= this.overdueMessageHandler.PickupOverdueP2PMessage(userID) ;
            
if(list == null)
            {
                
return ;
            }
            
if(this.sendDelay <=0)
            {
                
this.DoSend(list ,userID) ;
            }      
              
else
            {
                CbDoSend cb 
= new CbDoSend(this.DoSend) ;
                cb.BeginInvoke(list ,userID ,
null ,null) ;            
            }
        }        
        
#region DoSend
        
private void DoSend(IList msgList ,string userID )
        {
            
try
            {
                
if(this.sendDelay >0)
                {
                    System.Threading.Thread.Sleep(
this.sendDelay) ;
                }
                
                
foreach(NetMessage msg in msgList)
                {
                    
int result = this.toClientSender.HookAndSendMessage(userID ,msg) ;
                    
if(result != DataSendResult.Succeed)
                    {
                        
return ;
                    }
                }
                
this.overdueMessageHandler.SetOverdueMessageSended(userID) ;
            }
            
catch(Exception ee)
            {
                
this.esbLogger.Log(ee.GetType().ToString() ,ee.Message ,"ESFramework.Network.OverdueP2PMessageSender.DoSend" ,ErrorLevel.Standard) ;
            }
        }
        
#endregion
    }
    
internal delegate void CbDoSend(IList msgList ,string userID) ;

    注意,OverdueMessageSender借助OverdueMessageHandler来取出指定目标用户的OverdueMessage,并借助IToClientSender组件来发送这些OverdueMessage,最后,当发送成功,就调用OverdueMessageHandler的SetOverdueMessageSended方法。

    很多应用都要求在目标用户登录时,将属于他的OverdueMessage发送给它,这个时机可以从IBasicRequestDealer组件的SomeOneLogon事件切入,ESFramework对这一常见需求进行了支持,那就是OverdueMessageBridge。OverdueMessageBridge将OverdueMessageSender链接到这一时机。
   

    public
 
class
 OverdueMessageBridge
    {
        
#region
 BasicRequestDealer        
        
public
 IBasicRequestDealer BasicRequestDealer
        {
            
set
            {
                
if
(value 
!=
 
null
)
                {
                    value.SomeOneLogon 
+=
 
new
 CbLogon(value_SomeOneLogon);
                }                
            }
        }
        
#endregion
        
        
#region
 OverdueMessageSender
        
private
 OverdueMessageSender overdueMessageSender 
=
 
null
 ; 
        
public
  OverdueMessageSender OverdueMessageSender
        {
            
set
            {
                
this
.overdueMessageSender 
=
 value ;
            }
        }
        
#endregion
        
public
 OverdueMessageBridge()
        {            
        }
        
private
 
void
 value_SomeOneLogon(
string
 userID, NetMessage logonMsg)
        {
            
this
.overdueMessageSender.SendOverdueMessage(userID) ;
        }
    }

    如果你需要在其它时刻来发送OverdueMessage,自己构造一个对应的Bridge即可。

    细心的朋友可能会问,如果使用了Hook,那么Hook会不会对IOverdueMessageHandler.PickupOverdueP2PMessage()取出的消息产生影响?答案是不会。因为OverdueMessageSender采用的是和P2PMessageDealer一样的方式来发送OverdueMessage,所以如果存在Hook,OverdueMessage也会经过相同的Hook处理。

你可能感兴趣的文章
java与xml
查看>>
Javascript异步数据的同步处理方法
查看>>
iis6 zencart1.39 伪静态规则
查看>>
SQL Server代理(3/12):代理警报和操作员
查看>>
Linux备份ifcfg-eth0文件导致的网络故障问题
查看>>
2018年尾总结——稳中成长
查看>>
JFreeChart开发_用JFreeChart增强JSP报表的用户体验
查看>>
度量时间差
查看>>
通过jsp请求Servlet来操作HBASE
查看>>
Shell编程基础
查看>>
Shell之Sed常用用法
查看>>
3.1
查看>>
校验表单如何摆脱 if else ?
查看>>
<气场>读书笔记
查看>>
web安全问题分析与防御总结
查看>>
Centos下基于Hadoop安装Spark(分布式)
查看>>
3D地图的定时高亮和点击事件(基于echarts)
查看>>
mysql开启binlog
查看>>
设置Eclipse编码方式
查看>>
分布式系统唯一ID生成方案汇总【转】
查看>>