c#网络通信框架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内核解析之九 自定义处理方法的运行机制的更多相关文章
- c#网络通信框架networkcomms内核解析 序言
NetworkComms网络通信框架序言 networkcomms是我遇到的写的最优美的代码,很喜欢,推荐给大家:) 基于networkcomms2.3.1开源版本( gplv3)协议,写了一些文章, ...
- c#网络通信框架networkcomms内核解析之十 支持优先级的自定义线程池
NetworkComms网络通信框架序言 本例基于networkcomms2.3.1开源版本 gplv3协议 如果networkcomms是一顶皇冠,那么CommsThreadPool(自定义线程池 ...
- c#网络通信框架networkcomms内核解析之八 数据包的核心处理器
NetworkComms网络通信框架序言 本文基于networkcomms2.3.1开源版本 gplv3协议 我们先回顾一个 c#网络通信框架networkcomms内核解析之六 处理接收到的二进制 ...
- c#网络通信框架networkcomms内核解析之一 消息传送
networkcomms.net 来自英国的网络通信框架 官方网址 www.networkcomms.net 中文网址www.networkcomms.cn 在网络通信程序中,本地的类或者对象,要传输 ...
- c#网络通信框架networkcomms内核解析之一 消息传送2
networkcomms.net 来自英国的网络通信框架 官方网址 www.networkcomms.net 中文网址www.networkcomms.cn 在网络通信程序中,本地的类或者对象,要传输 ...
- c#网络通信框架networkcomms内核解析之三 消息同步调用
networkcomms.net 来自英国的网络通信框架 官方网址 www.networkcomms.net 中文网址www.networkcomms.cn 客户端发送消息给服务器,服务器计算结果返回 ...
- c#网络通信框架networkcomms内核解析之六 处理接收到的二进制数据
本文基于networkcomms2.3.1开源版本 gplv3协议 在networkcomms通信系统中,服务器端收到某连接上的数据后,数据会暂时存放在"数据包创建器"(Pack ...
- xenomai内核解析之信号signal(一)---Linux信号机制
版权声明:本文为本文为博主原创文章,转载请注明出处.如有错误,欢迎指正.博客地址:https://www.cnblogs.com/wsg1100/ 目录 1. Linux信号 1.1注册信号处理函数 ...
- xenomai内核解析之信号signal(二)---xenomai信号处理机制
xenomai信号 上篇文章讲了linux的信号在内核的发送与处理流程,现在加入了cobalt核,Cobalt内核为xenomai线程提供了信号机制.下面一一解析xenomai内核的信号处理机制. 1 ...
随机推荐
- vs2005水晶报表无法运行在X64机器上
要下载补丁:CRRedist2005_X64.msi http://download.csdn.net/download/gcy007/7106933
- postgresql流复制配置
一.配置环境: 示例环境 主机名 IP 角色 系统版本 数据目录 pg版本 db1 192.168.128.128 主库 RedHat5.3 /app/postgreSQL/data 9.1.7 db ...
- linux bash快捷键
bash快捷键 CTRL+F 光标向前移动一个字母 CTRL+B 光标向后移动一个字母 CTRL+A HOME CTRL+E END
- App创业者必看:如何选择免费数据分析平台
笔者是一位移动互联网老兵,做过好几个App的开发运营工作,其中一些如今侥幸有了上亿用户.今天和大家聊一下App开发中,不能缺少的一个工具——数据分析系统 首先,App创业者为什么需要一个数据分析系 ...
- adpatch options=hotpatch
--no need to shutdown application and no need to enable maintenance mode adpatch options=hotpatch fi ...
- html里面的相对路径和绝对路径
HTML有两种路径的写法:相对路径和绝对路径. 相对路径是在同一个目录的文件引用,如果源文件和引用文件在同一个目录里,直接写引用文件名即可. 如: a.html: c:\test\menu\a ...
- [问题2015S01] 复旦高等代数 II(14级)每周一题(第二教学周)
[问题2015S01] 设 \(M_n(\mathbb{R})\) 是 \(n\) 阶实方阵全体构成的实线性空间, \(\varphi\) 是 \(M_n(\mathbb{R})\) 上的线性变换, ...
- C++ string到底是什么
C++ string到底是什么? 要回答这个问题,先要了解什么是basic_string.看一下basic_string的声明: template < class charT, //定义字符串中 ...
- 初学画布canvas的chapter2
文本 1.字体属性 context.font = [css font property] ——使用CSS规范,语法跟CSS字体速记符号一致 ——line-height无效,并永远忽略 Context. ...
- How can I view currently running MySQL queries?( 查看正在运行的MySQL语句/脚本命令)
show processlist;show processlist\G;SHOW FULL PROCESSLIST;SHOW FULL PROCESSLIST\G; REF:http://dev.my ...