您的位置:首页 > 理论基础 > 计算机网络

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

2015-03-03 00:00 706 查看
本文基于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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐