zoukankan      html  css  js  c++  java
  • 可靠通信的保障 —— 使用ACK机制发送自定义信息——ESFramework 通信框架4.0 快速上手(12)

          (本文所介绍的新功能位于2011.04.18发布的最新版本中,此次版本变更请参见ESFramework通信框架通信框架 4.0 版本升级说明(持续更新)

          使用ESPlus.Application.CustomizeInfo.Passive.ICustomizeInfoOutter接口的Send方法,我们已经可以给服务端或其它在线客户端发送自定义信息了,那么,如何得知接收方是否已经收到了我们发出的信息了呢?特别是针对一些非常重要的信息,确认对方已经收到是非常重要的。ICustomizeInfoOutter接口增加了SendCertainly方法来解决这个问题。

    一.启用ACK机制

          ACK,即确认的意思。当我们发送一个自定义信息给对方时,对方收到信息后,回复一个ACK给我们,我们接收到了ACK,就知道对方一定收到信息了。

        

          ICustomizeInfoOutter接口的SendCertainly方法就是启用了带ACK机制的发送:

            /// <summary>
            
    /// 向服务器发送二进制信息,并等待服务器的ACK。当前调用线程会一直阻塞,直到收到ACK;如果超时都没有收到ACK,则将抛出Timeout异常。
            
    /// </summary>
            
    /// <param name="informationType">自定义信息类型</param>
            
    /// <param name="info">二进制信息</param>
            void SendCertainly(int informationType, byte[] info);

            
    /// <summary>
            
    /// 向在线用户targetUserID发送二进制信息,并等待其ACK。当前调用线程会一直阻塞,直到收到ACK;如果超时都没有收到ACK,则将抛出Timeout异常。
            
    /// </summary>
            
    /// <param name="targetUserID">接收消息的目标用户ID</param>
            
    /// <param name="informationType">自定义信息类型</param>
            
    /// <param name="info">二进制信息</param>      
            void SendCertainly(string targetUserID, int informationType, byte[] info);

          同样的,服务端ICustomizeInfoController接口的SendCertainly方法,也是启用了带ACK机制的发送:

            /// <summary>
            
    /// 向ID为userID的在线用户发送二进制信息,并等待其ACK。当前调用线程会一直阻塞,直到收到ACK;如果超时都没有收到ACK,则将抛出Timeout异常。
            
    /// </summary>
            
    /// <param name="userID">接收消息的用户ID</param>
            
    /// <param name="informationType">自定义信息类型</param>
            
    /// <param name="info">二进制信息</param>          
            void SendCertainly(string userID, int informationType, byte[] info);

    (1)无论是客户端发送信息给服务端、还是客户端发送信息给其它客户端、或者是服务端发送信息给客户端,它们采用的ACK机制的原理是一样的。

    (2)当框架接收到需要ACK的信息时,会自动回复ACK给发送方。这是由ESPlus底层自动完成的,应用程序不需要关心。

    (3)ESPlus会先回复ACK,然后才会调用处理信息的方法。所以,当发送方接收到ACK回复时,只是意味着接收方已经接收到了信息,并不表示接收方已经处理完了信息。

    (4)如果接收方在规定的时间内(默认为30秒)都没有收到ACK,则会抛出超时的异常。当然,在规定的时间内没有收到ACK,并不一定就是接收方没有收到信息,而是有几种可能性:

           a.由于网络慢,导致ACK延迟抵达发送方。

           b.接收方已经掉线。

           c.发送方已经掉线。

    (5)SendCertainly方法采用的是阻塞模型,即只有收到ACK后才会返回,否则一直阻塞当前调用线程。如果既需要ACK机制的发送,又不希望阻塞当前线程,那么,可以异步调用SendCertainly方法,并通过回调获知是否有超时异常。

    (6)ESPlus.Application.CustomizeInfo命名空间下的主要接口的方法已经比较多了,我们这里厘清一下。比如,客户端由ICustomizeInfoOutter接口发出的CommitRequest调用将被服务端ICustomizeInfoBusinessHandler接口的HandleRequest方法来处理,下图我们通过箭头将这些调用与处理关联起来:

         

    二.具有同样效果的同步调用

          使用自定义信息,我们还有几个同步调用的方法,比如ICustomizeInfoOutter接口的CommitRequest方法和CommitP2PRequest方法、以及ICustomizeInfoController接口的QueryClient方法,这些同步调用的方法都是有返回值的,如果超时没有收到返回的信息,也抛出超时异常。

          同步调用与带ACK机制的发送采用的是完全相同的模型,我们完全可以使用同步调用来模拟ACK机制,比如,需要确认的信息就使用同步调用发送,接收方在处理同步调用的时候直接返回null,就可以达到同样的效果。

           同步调用与带ACK机制的发送有两点小区别:

    (1)在同步调用中,接收方回复的是对应请求的答案;在带ACK机制的发送中,接收方回复的是ACK。

    (2)在同步调用中,接收方是处理完信息后才回复;在带ACK机制的发送中,接收方则是先回复ACK,再处理收到信息。

          由于同步调用和带ACK机制的发送都有可能超时抛出异常,所以,我们在程序中应当将其try...catch起来,以防止应用程序抛出未被截获的异常。 

     三.在消息骨架流程中挂接ACK机制

          如果不使用Rapid引擎,而自己来组装消息处理流程,我们就可以直接在消息骨架流程上,挂接一个自定义的IMessageSpy,来自动回复那些需要ACK的消息。并且,这种方式的优势在于,我们可以对任意类型的消息采用ACK机制,而本文介绍的SendCertainly方法只是针对自定义信息启用ACK机制。当然,对于Rapid引擎的使用者来说,用得最多的也就是自定义信息,所以,也应该足够了。(关于如何让协议类序列化达到最高性能且得到最精简的自定义信息,请参见ESFramework通信框架通信框架 4.0 快速上手(11) -- 使用紧凑的序列化器,数倍提升性能

     

    ESFramework通信框架通信框架 4.0 概述

    ESFramework通信框架通信框架 4.0 有哪些优点?

    ESFramework通信框架通信框架 4.0 版本升级说明(持续更新)

    《ESFramework通信框架通信框架 4.0 快速上手》系列所有文章

    《ESFramework通信框架通信框架 4.0 高级进阶》系列所有文章 

  • 相关阅读:
    一年足迹记录
    Scanf连续调用多次并且存在%c的问题
    Oracle学习计划
    SQL语句、PL/SQL语句、SQL*PLUS语句结束符号
    使用sys无法通过sqlplus或者sqldeveloper连接数据库
    把十进制转化为二进制的一种方法
    GTK+与QT的对比
    数据库崩溃后对redo log的使用
    产生不重复的随机牌
    失效试图,还有就是 还原试图。
  • 原文地址:https://www.cnblogs.com/zhuweisky/p/2016743.html
Copyright © 2011-2022 走看看