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. NetworkComms网络通信框架V3结构图

    NetworkComms网络通信框架序言 来自英国的c#网络通信框架,历时五年打造,由英国剑桥的2位工程师倾情开发,最新版本V3.x版本.

  5. 介绍开源的.net通信框架NetworkComms框架 源码分析

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 售价249英镑 我曾经花了 ...

  6. 成熟的C#网络通信框架介绍——ESFramework通信框架

    (转自:http://www.cnblogs.com/zhuweisky/archive/2010/08/12/1798211.html) ESFramework通信框架是一套性能卓越.稳定可靠.强大 ...

  7. GJM : Unity3D 常用网络框架与实战解析 【笔记】

    Unity常用网络框架与实战解析 1.Http协议          Http协议                  存在TCP 之上 有时候 TLS\SSL 之上 默认端口80 https 默认端口 ...

  8. Android 开源框架Universal-Image-Loader完全解析(三)---源代码解读

    转载请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/39057201),请尊重他人的辛勤劳动成果,谢谢! 本篇文章 ...

  9. Android 开源框架Universal-Image-Loader完全解析(二)--- 图片缓存策略详解

    转载请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/26810303),请尊重他人的辛勤劳动成果,谢谢! 本篇文章 ...

随机推荐

  1. 报表开发之批量导入导出excel

    在日常使用报表过程中,会有这样一种情况,你将Excel表分发给各个员工,员工填完后,统一整理成多个Excel,你需要将这些数据,用报表的填报功能,提交录入到数据库中,这样一来可避免到服务器机房录数据的 ...

  2. 检查失败,&lt;master&gt;分支有过其他更新,请先在本地合并&lt;master&gt;分支的代码

  3. 爱上WPF,努力才会有希望!

    从WinForm转向WPF开发已经有两个多月了,通过不断深入地学习与运用,现在是越来越爱它了.它实在是太强大了.运用WPF,你不仅可以做Win界面,也可以很快转向Web开发,因为Silverlight ...

  4. Java经典实例:纪元秒和本地日期时间互换

    Java版本:1.8开始 import java.time.Instant; import java.time.ZoneId; import java.time.ZonedDateTime; /** ...

  5. poj 1060

    http://poj.org/problem?id=1060 题意:多项式的运算的题目,不过这个运算有个特点,就是只要是同项的多项式,无论相加还是相减,都为0,给你三个多项式,分别为a,b,c. 要你 ...

  6. 几种不同的获取url地址的方法

    通过如下的几种方法,您就可以获取访问者访问您的网站的来路,请根据需要选择适合您的方法. 一.C#代码一 string url = Request["referer"]; Respo ...

  7. Android应用安全之Content Provider安全

    android平台提供了Content Provider,将一个应用程序的指定数据集提供给其它应用程序.这些数据可以存储在文件系统.SQLite数据库中,或以任何其它合理的方式存储.其他应用可以通过C ...

  8. Eclipse在线安装ADT插件

    要想使用Eclipse开发Android应用,首先要安装一个ADT插件,在此记录一下在Eclipse中采用在线安装的方式ADT插件,我使用的Eclipse版本是:eclipse-jee-luna-SR ...

  9. 怎样把function中的arguments变成普通数组

    当我们在写一个具有处理可变长度参数的函数时,需要对arguments做一些操作.但是arguments它并不是一个数组,没有数组的各种操作,而且,JS的严格模式中不允许更改它的值. 这时我们需要将它的 ...

  10. 语义Web和本体开发相关技术

    在技术实现方面,语义Web和本体理论的研究日趋成熟,已经有许多成熟的工具或程序接口,诸如Jena.OWL API等API是系统实现的关键技术.这里介绍系统的可行性分析以及系统开发设计的关键技术. 1 ...