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 ...
随机推荐
- top命令下的各种指标意义
linux操作系统中top命令中各cpu含义: us 用户空间占用CPU百分比 sy 内核空间占用CPU百分比 ni 用户进程空间内改变过优先级的进程占用CPU百分比 id 空闲CPU百分比 wa 等 ...
- 什么是FOUC?如何避免FOUC?///////////////////////////zzzz
一个新的名词叫做 FOUC 浏览器样式闪烁,之前也听说过一些类似的东西,比如样式突变等等,但这东西竟然有学名的..什么是FOUC(文档样式短暂失效)?如果使用import方法对CSS进行导入,会导致 ...
- http://www.miniui.com/demo/#src=datagrid/celledit.html
http://www.miniui.com/demo/#src=datagrid/celledit.html jQuery MiniUI Demo
- 图片按钮来代替文件上传控件(Freemaker,JQuery,HTML,CSS,JavaScript)
CSS样式: <style type="text/css"> .fileInputContainer{ height:70px; width:95px; positio ...
- nginx安装ssl
http://wiki.nginx.org/Modules#Standard_HTTP_modules 这里面带有所有基本的模块,及需要额外增加的模块 1.安装带有ssl模块的 nginx wget ...
- Locality Sensitive Hash 局部敏感哈希
Locality Sensitive Hash是一种常见的用于处理高维向量的索引办法.与其它基于Tree的数据结构,诸如KD-Tree.SR-Tree相比,它较好地克服了Curse of Dimens ...
- Spark 1.1.0 编译(为了支持hbase 0.98.6)
为了支持hbase0.98.6,需要重新编译spark 1. 下载spark 1.1.0源代码,以及 scala-2.10.4的bin包. 将环境变量 SCALA_HOME 设置为 scala-2.1 ...
- centos6.6编译安装lnmp系列之nginx
简介: 环境:虚拟机+centos6.6 Cmake下载地址:http://www.cmake.org/files/v3.0/cmake-3.0.2.tar.gz Nginx 下载地址: http:/ ...
- [转](二)unity4.6Ugui中文教程文档-------概要-UGUI Canvas
大家好,我是孙广东. 转载请注明出处:http://write.blog.csdn.net/postedit/38922399 更全的内容请看我的游戏蛮牛地址:http://www.unityma ...
- Ubuntu 16.04 + Caffe
主要参考: https://github.com/BVLC/caffe/wiki/Ubuntu-16.04-or-15.10-Installation-Guide http://caffe.berke ...