NetworkComms网络通信框架序言

本文基于networkcomms2.3.1开源版本  gplv3协议

我们自己写的处理方法都称之为自定义处理方法

比如,我们在服务器上写的与登陆相关的处理方法:

NetworkComms.AppendGlobalIncomingPacketHandler<LoginContract>("ReqLogin", IncomingLoginRequest);
   private void IncomingLoginRequest(PacketHeader header, Connection connection, LoginContract loginContract)
        {
            try
            {
                string resMsg="";
                //为了简单,这里不调用数据库,而是模拟一下登录
                ")

                    resMsg = "登录成功";

                else

                    resMsg = "用户名密码错误";
                //把返回结果写入到契约类中,后面返回给客户端
                ResMsgContract contract = new ResMsgContract();
                contract.Message = resMsg;

                connection.SendObject("ResLogin", contract);

            }
            catch (Exception ex)
            {

            }
        }

通过以上的写法,当服务器器收到消息类型为“ReqLogin"的消息时,会自动获取到相关的处理方法。

我们看一下背后的运行机制。

首先看注册语句:

NetworkComms.AppendGlobalIncomingPacketHandler<LoginContract>("ReqLogin", IncomingLoginRequest);
AppendGlobalIncomingPacketHandler()方法,把消息类型”ReqLogin"和处理方法“INcomingLoginRequest"添加到NetworkComms静态类的字典中:

在AppendGlobalIncomingPacketHander<T>方法中 ,我们的处理方法 IncomingLoginRequest 与 PacketHandlerCallBackDelegate<T>参数相对应。

来看一下PacketHandlerCallBackDelegate的定义
      public delegate void PacketHandlerCallBackDelegate<T>(PacketHeader packetHeader, Connection connection, T incomingObject);
AppendGlobalIncomingPacketHandler()方法如下:
    public static void AppendGlobalIncomingPacketHandler<T>(string packetTypeStr, PacketHandlerCallBackDelegate<T> packetHandlerDelgatePointer)
        {
            if (packetTypeStr == null) throw new ArgumentNullException("packetTypeStr", "Provided packetType string cannot be null.");
            if (packetHandlerDelgatePointer == null) throw new ArgumentNullException("packetHandlerDelgatePointer", "Provided PacketHandlerCallBackDelegate<T> cannot be null.");
            if (sendReceiveOptions == null) throw new ArgumentNullException("sendReceiveOptions", "Provided SendReceiveOptions cannot be null.");

            lock (globalDictAndDelegateLocker)
            {

                if (globalIncomingPacketUnwrappers.ContainsKey(packetTypeStr))
                {
                    //Make sure if we already have an existing entry that it matches with the provided
                    if (!globalIncomingPacketUnwrappers[packetTypeStr].Options.OptionsCompatible(sendReceiveOptions))
                        throw new PacketHandlerException("The proivded SendReceiveOptions are not compatible with existing SendReceiveOptions already specified for this packetTypeStr.");
                }
                else
                    globalIncomingPacketUnwrappers.Add(packetTypeStr, new PacketTypeUnwrapper(packetTypeStr, sendReceiveOptions));

                //Ad the handler to the list
                if (globalIncomingPacketHandlers.ContainsKey(packetTypeStr))
                {
                    //Make sure we avoid duplicates
                    PacketTypeHandlerDelegateWrapper<T> toCompareDelegate = new PacketTypeHandlerDelegateWrapper<T>(packetHandlerDelgatePointer);

                    bool delegateAlreadyExists = false;
                    foreach (var handler in globalIncomingPacketHandlers[packetTypeStr])
                    {
                        if (handler == toCompareDelegate)
                        {
                            delegateAlreadyExists = true;
                            break;
                        }
                    }

                    if (delegateAlreadyExists)
                        throw new PacketHandlerException("This specific packet handler delegate already exists for the provided packetTypeStr.");
                    //把处理方法添加到相关字典中
                    globalIncomingPacketHandlers[packetTypeStr].Add(new PacketTypeHandlerDelegateWrapper<T>(packetHandlerDelgatePointer));
                }
                else
                    globalIncomingPacketHandlers.Add(packetTypeStr, new List<IPacketTypeHandlerDelegateWrapper>() { new PacketTypeHandlerDelegateWrapper<T>(packetHandlerDelgatePointer) });

                if (LoggingEnabled) logger.Info("Added incoming packetHandler for '" + packetTypeStr + "' packetType.");
            }
        }

字典:

        static Dictionary<string, List<IPacketTypeHandlerDelegateWrapper>> globalIncomingPacketHandlers = new Dictionary<string, List<IPacketTypeHandlerDelegateWrapper>>();

我们看到上面有一句:

 PacketTypeHandlerDelegateWrapper<T> toCompareDelegate = new PacketTypeHandlerDelegateWrapper<T>(packetHandlerDelgatePointer);

看一下PacketTypeHandlerDelegateWrapper类,此类把处理方法作为参数。

我们看一下此类:

class PacketTypeHandlerDelegateWrapper<T> : IPacketTypeHandlerDelegateWrapper
    {
        NetworkComms.PacketHandlerCallBackDelegate<T> innerDelegate;

        public PacketTypeHandlerDelegateWrapper(NetworkComms.PacketHandlerCallBackDelegate<T> packetHandlerDelegate)
        {
            this.innerDelegate = packetHandlerDelegate;
        }

        public object DeSerialize(MemoryStream incomingBytes, SendReceiveOptions options)
        {
            if (incomingBytes == null) return null;
            //if (incomingBytes == null || incomingBytes.Length == 0) return null;
            else
            //{
                //if (options.DataSerializer == null)
                //    throw new ArgumentNullException("options", "The provided options.DataSerializer was null. Cannot continue with deserialise.");

                return options.DataSerializer.DeserialiseDataObject<T>(incomingBytes, options.DataProcessors, options.Options);
            //}
        }

        public void Process(PacketHeader packetHeader, Connection connection, object obj)
        {
            innerDelegate(packetHeader, connection, (obj == null ? default(T) : (T)obj));
        }

        public bool Equals(IPacketTypeHandlerDelegateWrapper other)
        {
            if (innerDelegate == (other as PacketTypeHandlerDelegateWrapper<T>).innerDelegate)
                return true;
            else
                return false;
        }

        public bool EqualsDelegate(Delegate other)
        {
            return other as NetworkComms.PacketHandlerCallBackDelegate<T> == innerDelegate;
        }
    }

感觉这一章写的不太清楚,水平有限,您可以自行阅读一下networkcomms2.3.1开源版本的源代码,获取会看的比较清晰:)

www.cnblogs.com/networkcomms

www.networkcomms.cn

c#网络通信框架networkcomms内核解析之九 自定义处理方法的运行机制的更多相关文章

  1. c#网络通信框架networkcomms内核解析 序言

    NetworkComms网络通信框架序言 networkcomms是我遇到的写的最优美的代码,很喜欢,推荐给大家:) 基于networkcomms2.3.1开源版本( gplv3)协议,写了一些文章, ...

  2. c#网络通信框架networkcomms内核解析之十 支持优先级的自定义线程池

    NetworkComms网络通信框架序言 本例基于networkcomms2.3.1开源版本  gplv3协议 如果networkcomms是一顶皇冠,那么CommsThreadPool(自定义线程池 ...

  3. c#网络通信框架networkcomms内核解析之八 数据包的核心处理器

    NetworkComms网络通信框架序言 本文基于networkcomms2.3.1开源版本  gplv3协议 我们先回顾一个 c#网络通信框架networkcomms内核解析之六 处理接收到的二进制 ...

  4. c#网络通信框架networkcomms内核解析之一 消息传送

    networkcomms.net 来自英国的网络通信框架 官方网址 www.networkcomms.net 中文网址www.networkcomms.cn 在网络通信程序中,本地的类或者对象,要传输 ...

  5. c#网络通信框架networkcomms内核解析之一 消息传送2

    networkcomms.net 来自英国的网络通信框架 官方网址 www.networkcomms.net 中文网址www.networkcomms.cn 在网络通信程序中,本地的类或者对象,要传输 ...

  6. c#网络通信框架networkcomms内核解析之三 消息同步调用

    networkcomms.net 来自英国的网络通信框架 官方网址 www.networkcomms.net 中文网址www.networkcomms.cn 客户端发送消息给服务器,服务器计算结果返回 ...

  7. c#网络通信框架networkcomms内核解析之六 处理接收到的二进制数据

    本文基于networkcomms2.3.1开源版本  gplv3协议 在networkcomms通信系统中,服务器端收到某连接上的数据后,数据会暂时存放在"数据包创建器"(Pack ...

  8. xenomai内核解析之信号signal(一)---Linux信号机制

    版权声明:本文为本文为博主原创文章,转载请注明出处.如有错误,欢迎指正.博客地址:https://www.cnblogs.com/wsg1100/ 目录 1. Linux信号 1.1注册信号处理函数 ...

  9. xenomai内核解析之信号signal(二)---xenomai信号处理机制

    xenomai信号 上篇文章讲了linux的信号在内核的发送与处理流程,现在加入了cobalt核,Cobalt内核为xenomai线程提供了信号机制.下面一一解析xenomai内核的信号处理机制. 1 ...

随机推荐

  1. Mysql 语句中对关键字进行转义的方式

    在SQLserver中, 对列名表名库名Owner进行转义使用的是[ ] 这个我在其他文章中讲过 ,而且这是一个很好的习惯! 同理  在MySql中 也建议对表名等进行转移  使用的方式是 ``  就 ...

  2. Python快速建站系列-Part.Five.1-个人主页及发表文章

    |版权声明:本文为博主原创文章,未经博主允许不得转载. 现在的TSSS已经有了注册和登录的功能,首页的内容也填充好了,那这一节就完成用户个人主页的内容和发表文章功能的实现. 先完成用户个人主页的use ...

  3. 13. 星际争霸之php设计模式--正面模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  4. 关于Block的copy和循环引用的问题

    http://blog.csdn.net/felix9/article/details/9619313 在实际开发中,发现使用Block有着比delegate和notification更简洁的优势.于 ...

  5. C++ 学习笔记(3) —— 內联函数

    内联函数的用处: 用空间换取时间,在调用时不用每次都写调用的汇编. 什么时候内联: 比较小的函数:只有两三行 在循环里循环调用的函数 什么时候不内联: 比较大的函数,2.30行的 递归的函数

  6. 数位DP 求K进制下0~N的每个数每位上出现的数的总和

    好久没写博客了,因为感觉时间比较紧,另一方面没有心思,做的题目比较浅也是另一方面. 热身赛第二场被血虐了好不好,于是决定看看数位DP吧. 进入正题: 如题是一道经(简)典(单)的数位dp. 第一步,对 ...

  7. Openstack的项目管理方案

    openstack作为云的解决方案,必须对某个用户,项目具有资源限制,不能无限制使用资源. 配置 在/etc/nova/nova.conf中,有 quota_driver=nova.quota.DbQ ...

  8. 跟着8张思维导图学习javascript

    学习的道路就是要不断的总结归纳,好记性不如烂笔头,so,下面将po出8张javascript相关的思维导图. 思维导图小tips:思维导图又叫心智图,是表达发射性思维的有效的图形思维工具 ,它简单却又 ...

  9. Android中AIDL通信机制分析

    一.背景 ·1.AIDL出现的原因 在android系统中,每一个程序都是运行在自己的进程中,进程之间无法进行通讯,为了在Android平台,一个进程通常不能访问另一个进程的内存空间,所以要想对话,需 ...

  10. WordCount示例深度学习MapReduce过程(1)

    我们都安装完Hadoop之后,按照一些案例先要跑一个WourdCount程序,来测试Hadoop安装是否成功.在终端中用命令创建一个文件夹,简单的向两个文件中各写入一段话,然后运行Hadoop,Wou ...