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

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

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

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

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

                    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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值