介绍开源的.net通信框架NetworkComms框架 源码分析(十八 ) ConnectionListenerBase
原文网址: http://www.cnblogs.com/csdev
Networkcomms 是一款C# 语言编写的TCP/UDP通信框架 作者是英国人 以前是收费的 目前作者已经开源 许可是:Apache License v2
开源地址是:https://github.com/MarcFletcher/NetworkComms.Net
连接监听器基类
/// <summary> /// A base class that the listener of each connection type inherits from. /// This allows NetworkComms.Net to manage listeners at the general connection level. /// 连接监听器基类 /// </summary> public abstract class ConnectionListenerBase { #region Public Properties /// <summary> /// The send receive options associated with this listener. /// 监听器使用的收发参数类 /// </summary> public SendReceiveOptions ListenerDefaultSendReceiveOptions { get; protected set; } /// <summary> /// The connection type that this listener supports. /// 连接类型 /// </summary> public ConnectionType ConnectionType { get; protected set; } /// <summary> /// The application layer protocol status for this listener. /// 应用层协议 /// </summary> public ApplicationLayerProtocolStatus ApplicationLayerProtocol { get; protected set; } /// <summary> /// True if this listener is listening. /// 是否在监听中 /// </summary> public bool IsListening { get; protected set; } /// <summary> /// True if this listener will be advertised via peer discovery /// 设置为True 则可以通过Peer discovery被发现 /// </summary> public bool IsDiscoverable { get; protected set; } /// <summary> /// The local IPEndPoint that this listener is associated with. /// 本地IP端点 /// </summary> public EndPoint LocalListenEndPoint { get; protected set; } #endregion #region Private Properties /// <summary> /// Thread safety locker which is used when accessing <see cref="incomingPacketHandlers"/> /// and <see cref="incomingPacketUnwrappers"/> /// 同步锁 用于线程安全 /// </summary> private object delegateLocker = new object(); /// <summary> /// By default all incoming objects are handled using ListenerDefaultSendReceiveOptions. Should the user want something else /// those settings are stored here ///字典 用于存储 ( 消息类型与 数据包展开器) /// 数据包展开器的作用是 对应消息类型与收发参数类 /// </summary> private Dictionary<string, PacketTypeUnwrapper> incomingPacketUnwrappers = new Dictionary<string, PacketTypeUnwrapper>(); /// <summary> /// A listener specific incoming packet handler dictionary. These are called before any global handlers ///字典 用于存储 ( 消息类型 与对应的处理器列表) /// </summary> private Dictionary<string, List<IPacketTypeHandlerDelegateWrapper>> incomingPacketHandlers = new Dictionary<string, List<IPacketTypeHandlerDelegateWrapper>>(); #endregion /// <summary> /// Create a new listener instance /// 创建一个监听器实例 /// </summary> /// <param name="connectionType">连接类型 The connection type to listen for.</param> /// <param name="sendReceiveOptions">收发参数 The send receive options to use for this listener</param> /// <param name="applicationLayerProtocol">应用层协议 If enabled NetworkComms.Net uses a custom /// application layer protocol to provide useful features such as inline serialisation, /// transparent packet transmission, remote peer handshake and information etc. We strongly /// recommend you enable the NetworkComms.Net application layer protocol.</param> /// <param name="allowDiscoverable">是否允许被其他端点发现 Determines if the newly created <see cref="ConnectionListenerBase"/> will be discoverable if <see cref="Tools.PeerDiscovery"/> is enabled.</param> protected ConnectionListenerBase(ConnectionType connectionType, SendReceiveOptions sendReceiveOptions, ApplicationLayerProtocolStatus applicationLayerProtocol, bool allowDiscoverable) { if (connectionType == ConnectionType.Undefined) throw new ArgumentException("ConnectionType.Undefined is not valid when calling this method.", "connectionType"); if (sendReceiveOptions == null) throw new ArgumentNullException("sendReceiveOptions", "Provided send receive option may not be null."); if (applicationLayerProtocol == ApplicationLayerProtocolStatus.Undefined) throw new ArgumentException("ApplicationLayerProtocolStatus.Undefined is not valid when calling this method.", "applicationLayerProtocol"); //Validate SRO options if the application layer protocol is disabled //如果应用层协议禁用 验证收发参数类 if (applicationLayerProtocol == ApplicationLayerProtocolStatus.Disabled) { if (sendReceiveOptions.Options.ContainsKey("ReceiveConfirmationRequired")) throw new ArgumentException("Attempted to create an unmanaged connection when the provided send receive" + " options specified the ReceiveConfirmationRequired option. Please provide compatible send receive options in order to successfully" + " instantiate this unmanaged connection.", "sendReceiveOptions"); if (sendReceiveOptions.DataSerializer != DPSManager.GetDataSerializer<NullSerializer>()) throw new ArgumentException("Attempted to create an unmanaged connection when the provided send receive" + " options serialiser was not NullSerializer. Please provide compatible send receive options in order to successfully" + " instantiate this unmanaged connection.", "sendReceiveOptions"); ) throw new ArgumentException("Attempted to create an unmanaged connection when the provided send receive" + " options contains data processors. Data processors may not be used with unmanaged connections." + " Please provide compatible send receive options in order to successfully instantiate this unmanaged connection.", "sendReceiveOptions"); } if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Info("Created new connection listener (" + connectionType.ToString() + "-" + (applicationLayerProtocol == ApplicationLayerProtocolStatus.Enabled ? "E" : "D") + ")."); this.ConnectionType = connectionType; this.ListenerDefaultSendReceiveOptions = sendReceiveOptions; this.ApplicationLayerProtocol = applicationLayerProtocol; this.IsDiscoverable = allowDiscoverable; } /// <summary> /// Returns a clean string containing the current listener state /// 返回当前监听器的监听状态 /// </summary> /// <returns></returns> public override string ToString() { string returnString = "[" + ConnectionType.ToString() + "-" + (ApplicationLayerProtocol == ApplicationLayerProtocolStatus.Enabled ? "E" : "D") + "] "; if (IsListening && LocalListenEndPoint != null) return returnString + "Listening - " + LocalListenEndPoint.ToString(); else return returnString + "Not Listening"; } #region Start and Stop Listening /// <summary> /// Start listening for incoming connections. /// 开始监听进入的连接 /// </summary> /// <param name="desiredLocalListenEndPoint">Try to start listening on this EndPoint.</param> /// <param name="useRandomPortFailOver">If the request EndPoint is unavailable fail over to a random port.</param> internal abstract void StartListening(EndPoint desiredLocalListenEndPoint, bool useRandomPortFailOver); /// <summary> /// Stop listening for incoming connections. /// 停止监听 /// </summary> internal abstract void StopListening(); #endregion #region Listener Specific Packet Handlers /// <summary> /// Append a listener specific packet handler using the listener default SendReceiveOptions /// 添加一个监听器指定的数据包处理器 使用默认的收发参数 /// </summary> /// <typeparam name="incomingObjectType">The type of incoming object</typeparam> /// <param name="packetTypeStr">The packet type for which this handler will be executed</param> /// <param name="packetHandlerDelgatePointer">The delegate to be executed when a packet of packetTypeStr is received</param> public void AppendIncomingPacketHandler<incomingObjectType>(string packetTypeStr, NetworkComms.PacketHandlerCallBackDelegate<incomingObjectType> packetHandlerDelgatePointer) { AppendIncomingPacketHandler<incomingObjectType>(packetTypeStr, packetHandlerDelgatePointer, ListenerDefaultSendReceiveOptions); } /// <summary> /// Append a listener specific packet handler /// 添加一个监听器指定的数据包处理器 使用指定的收发参数 /// </summary> /// <typeparam name="incomingObjectType">进入的数据 The type of incoming object</typeparam> /// <param name="packetTypeStr">消息类型 The packet type for which this handler will be executed</param> /// <param name="packetHandlerDelgatePointer">处理器 The delegate to be executed when a packet of packetTypeStr is received</param> /// <param name="options">收发参数 The <see cref="SendReceiveOptions"/> to be used for the provided packet type</param> public void AppendIncomingPacketHandler<incomingObjectType>(string packetTypeStr, NetworkComms.PacketHandlerCallBackDelegate<incomingObjectType> packetHandlerDelgatePointer, SendReceiveOptions options) { if (packetTypeStr == null) throw new ArgumentNullException("packetTypeStr", "Provided packetType string cannot be null."); if (packetHandlerDelgatePointer == null) throw new ArgumentNullException("packetHandlerDelgatePointer", "Provided NetworkComms.PacketHandlerCallBackDelegate<incomingObjectType> cannot be null."); if (options == null) throw new ArgumentNullException("options", "Provided SendReceiveOptions cannot be null."); //If we are adding a handler for an unmanaged packet type the data serializer must be NullSerializer //Checks for unmanaged packet types //如果我们给“非托管”的数据类型添加序列化器,必须是NullSerializer //检查“非托管”数据包类型 “非托管”主要在与其他语言的通信场景中使用 if (packetTypeStr == Enum.GetName(typeof(ReservedPacketType), ReservedPacketType.Unmanaged)) { if (options.DataSerializer != DPSManager.GetDataSerializer<NullSerializer>()) throw new ArgumentException("Attempted to add packet handler for an unmanaged packet type when the provided send receive options serializer was not NullSerializer."); ) throw new ArgumentException("Attempted to add packet handler for an unmanaged packet type when the provided send receive options contains data processors. Data processors may not be used inline with unmanaged packet types."); } lock (delegateLocker) { if (incomingPacketUnwrappers.ContainsKey(packetTypeStr)) { //Make sure if we already have an existing entry that it matches with the provided //如果收发参数前后不一致 抛出异常 if (!incomingPacketUnwrappers[packetTypeStr].Options.OptionsCompatible(options)) throw new PacketHandlerException("The provided SendReceiveOptions are not compatible with existing SendReceiveOptions already specified for this packetTypeStr."); } else incomingPacketUnwrappers.Add(packetTypeStr, new PacketTypeUnwrapper(packetTypeStr, options)); //Ad the handler to the list //添加处理器到列表中 if (incomingPacketHandlers.ContainsKey(packetTypeStr)) { //Make sure we avoid duplicates //确保不重复 PacketTypeHandlerDelegateWrapper<incomingObjectType> toCompareDelegate = new PacketTypeHandlerDelegateWrapper<incomingObjectType>(packetHandlerDelgatePointer); bool delegateAlreadyExists = false; foreach (var handler in incomingPacketHandlers[packetTypeStr]) { if (handler == toCompareDelegate) { delegateAlreadyExists = true; break; } } if (delegateAlreadyExists) throw new PacketHandlerException("This specific packet handler delegate already exists for the provided packetTypeStr."); incomingPacketHandlers[packetTypeStr].Add(new PacketTypeHandlerDelegateWrapper<incomingObjectType>(packetHandlerDelgatePointer)); } else incomingPacketHandlers.Add(packetTypeStr, new List<IPacketTypeHandlerDelegateWrapper>() { new PacketTypeHandlerDelegateWrapper<incomingObjectType>(packetHandlerDelgatePointer) }); if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Info("Added listener specific incoming packetHandler for '" + packetTypeStr + "' packetType on listener " + ToString()); } } /// <summary> /// Append a listener specific unmanaged packet handler /// 为“非托管”数据包添加处理器 /// </summary> /// <param name="packetHandlerDelgatePointer">The delegate to be executed when an unmanaged packet is received</param> public void AppendIncomingUnmanagedPacketHandler(NetworkComms.PacketHandlerCallBackDelegate<byte[]> packetHandlerDelgatePointer) { AppendIncomingPacketHandler<byte[]>(Enum.GetName(typeof(ReservedPacketType), ReservedPacketType.Unmanaged), packetHandlerDelgatePointer, new SendReceiveOptions<NullSerializer>()); } /// <summary> /// Returns true if an unmanaged packet handler exists on this listener /// 如果“非托管”数据包存在对应的处理器 返回True /// </summary> /// <param name="packetTypeStr">The packet type for which to check incoming packet handlers</param> /// <returns>True if a packet handler exists</returns> public bool IncomingPacketHandlerExists(string packetTypeStr) { lock (delegateLocker) return incomingPacketHandlers.ContainsKey(packetTypeStr); } /// <summary> /// Returns true if a listener specific unmanaged packet handler exists, on this listener. /// 如果监听器指定的“未托管”数据包处理器存在 返回True /// </summary> /// <returns>True if an unmanaged packet handler exists</returns> public bool IncomingUnmanagedPacketHandlerExists() { lock (delegateLocker) return incomingPacketHandlers.ContainsKey(Enum.GetName(typeof(ReservedPacketType), ReservedPacketType.Unmanaged)); } /// <summary> /// Returns true if the provided listener specific packet handler has been added for the provided packet type, on this listener. /// 如果某消息类型 对应的处理器已经存在 返回True /// </summary> /// <param name="packetTypeStr">消息类型 The packet type within which to check packet handlers</param> /// <param name="packetHandlerDelgatePointer">处理器 The packet handler to look for</param> /// <returns>True if a listener specific packet handler exists for the provided packetType</returns> public bool IncomingPacketHandlerExists(string packetTypeStr, Delegate packetHandlerDelgatePointer) { lock (delegateLocker) { if (incomingPacketHandlers.ContainsKey(packetTypeStr)) { foreach (var handler in incomingPacketHandlers[packetTypeStr]) if (handler.EqualsDelegate(packetHandlerDelgatePointer)) return true; } } return false; } /// <summary> /// Returns true if the provided listener specific unmanaged packet handler has been added, on this listener. /// 如果“未托管”数据包对应的处理器已经存在 返回True /// </summary> /// <param name="packetHandlerDelgatePointer">The packet handler to look for</param> /// <returns>True if a listener specific unmanaged packet handler exists</returns> public bool IncomingUnmanagedPacketHandlerExists(Delegate packetHandlerDelgatePointer) { lock (delegateLocker) { if (incomingPacketHandlers.ContainsKey(Enum.GetName(typeof(ReservedPacketType), ReservedPacketType.Unmanaged))) { foreach (var handler in incomingPacketHandlers[Enum.GetName(typeof(ReservedPacketType), ReservedPacketType.Unmanaged)]) if (handler.EqualsDelegate(packetHandlerDelgatePointer)) return true; } } return false; } /// <summary> /// Remove the provided listener specific packet handler for the specified packet type, on this listener. /// 根据参数中的消息类型 删除相应的处理器 /// </summary> /// <param name="packetTypeStr">消息类型 Packet type for which this delegate should be removed</param> /// <param name="packetHandlerDelgatePointer">处理器 The delegate to remove</param> public void RemoveIncomingPacketHandler(string packetTypeStr, Delegate packetHandlerDelgatePointer) { lock (delegateLocker) { if (incomingPacketHandlers.ContainsKey(packetTypeStr)) { //Remove any instances of this handler from the delegates //The bonus here is if the delegate has not been added we continue quite happily //从委托列表中删除这个处理器的任何实例 //如果处理器尚未添加也很好 IPacketTypeHandlerDelegateWrapper toRemove = null; foreach (var handler in incomingPacketHandlers[packetTypeStr]) { if (handler.EqualsDelegate(packetHandlerDelgatePointer)) { toRemove = handler; break; } } if (toRemove != null) incomingPacketHandlers[packetTypeStr].Remove(toRemove); ) { incomingPacketHandlers.Remove(packetTypeStr); //Remove any entries in the unwrappers dict as well as we are done with this packetTypeStr //从字典中删除相应消息的处理器 if (incomingPacketHandlers.ContainsKey(packetTypeStr)) incomingPacketHandlers.Remove(packetTypeStr); if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Info("Removed a listener specific packetHandler for '" + packetTypeStr + "' packetType. No handlers remain on listener " + ToString()); } else if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Info("Removed a listener specific packetHandler for '" + packetTypeStr + "' packetType. Handlers remain on listener " + ToString()); } } } /// <summary> /// Remove the provided listener specific unmanaged packet handler, on this listener. /// 删除“为托管”数据包处理器 /// </summary> /// <param name="packetHandlerDelgatePointer">The delegate to remove</param> public void RemoveIncomingUnmanagedPacketHandler(Delegate packetHandlerDelgatePointer) { RemoveIncomingPacketHandler(Enum.GetName(typeof(ReservedPacketType), ReservedPacketType.Unmanaged), packetHandlerDelgatePointer); } /// <summary> /// Removes all listener specific packet handlers for the provided packet type, on this listener. /// 根据消息类型 删除处理器 /// </summary> /// <param name="packetTypeStr">消息类型 Packet type for which all delegates should be removed</param> public void RemoveIncomingPacketHandler(string packetTypeStr) { lock (delegateLocker) { //We don't need to check for potentially removing a critical reserved packet handler here because those cannot be removed. if (incomingPacketHandlers.ContainsKey(packetTypeStr)) { incomingPacketHandlers.Remove(packetTypeStr); if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Info("Removed all listener specific incoming packetHandlers for '" + packetTypeStr + "' packetType on listener " + ToString()); } } } /// <summary> /// Removes all unmanaged packet handlers, on this listener. /// 删除所有的“为托管”数据包处理器 /// </summary> public void RemoveIncomingUnmanagedPacketHandler() { RemoveIncomingPacketHandler(Enum.GetName(typeof(ReservedPacketType), ReservedPacketType.Unmanaged)); } /// <summary> /// Removes all packet handlers for all packet types, on this listener. /// 删除所有的数据包处理器 /// </summary> public void RemoveIncomingPacketHandler() { lock (delegateLocker) { incomingPacketHandlers = new Dictionary<string, List<IPacketTypeHandlerDelegateWrapper>>(); if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Info("Removed all listener specific incoming packetHandlers for all packetTypes on listener " + ToString()); } } /// <summary> /// Add all listener specific packet handlers to the provided connection /// 添加所有的数据包处理器到指定的连接上 /// </summary> /// <param name="connection">连接 The connection to which packet handlers should be added</param> internal void AddListenerPacketHandlersToConnection(Connection connection) { lock (delegateLocker) { foreach (string packetType in incomingPacketHandlers.Keys) { foreach (IPacketTypeHandlerDelegateWrapper handler in incomingPacketHandlers[packetType]) connection.AppendIncomingPacketHandler(packetType, handler, incomingPacketUnwrappers[packetType].Options); } } if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Info("Appended connection specific packet handlers from listener '" + ToString() + "' to connection '" + connection.ToString() + "'."); } #endregion }
介绍开源的.net通信框架NetworkComms框架 源码分析(十八 ) ConnectionListenerBase的更多相关文章
- DotNetty网络通信框架学习之源码分析
DotNetty网络通信框架学习之源码分析 有关DotNetty框架,网上的详细资料不是很多,有不多的几个博友做了简单的介绍,也没有做深入的探究,我也根据源码中提供的demo做一下记录,方便后期查阅. ...
- 深入理解分布式调度框架TBSchedule及源码分析
简介 由于最近工作比较忙,前前后后花了两个月的时间把TBSchedule的源码翻了个底朝天.关于TBSchedule的使用,网上也有很多参考资料,这里不做过多的阐述.本文着重介绍TBSchedule的 ...
- 设计模式(十五)——命令模式(Spring框架的JdbcTemplate源码分析)
1 智能生活项目需求 看一个具体的需求 1) 我们买了一套智能家电,有照明灯.风扇.冰箱.洗衣机,我们只要在手机上安装 app 就可以控制对这些家电工作. 2) 这些智能家电来自不同的厂家,我们不想针 ...
- 设计模式(二十一)——解释器模式(Spring 框架中SpelExpressionParser源码分析)
1 四则运算问题 通过解释器模式来实现四则运算,如计算 a+b-c 的值,具体要求 1) 先输入表达式的形式,比如 a+b+c-d+e, 要求表达式的字母不能重复 2) 在分别输入 a ,b, c, ...
- $Django cbv源码分析 djangorestframework框架之APIView源码分析
1 CBV的源码分析 #视图 class login (View): pass #路由 url(r'^books/$', views.login.as_view()) #阅读源码: #左侧工程栏--- ...
- ④NuPlayer播放框架之Renderer源码分析
[时间:2016-11] [状态:Open] [关键词:android,nuplayer,开源播放器,播放框架,渲染器,render] 0 导读 之前我们分析了NuPlayer的实现代码,本文将重点聚 ...
- ⑤NuPlayer播放框架之GenericSource源码分析
[时间:2017-01] [状态:Open] [关键词:android,nuplayer,开源播放器,播放框架,GenericSource] 0 导读 GenericSource是NuPlayer:: ...
- ③NuPlayer播放框架之类NuPlayer源码分析
[时间:2016-10] [状态:Open] [关键词:android,nuplayer,开源播放器,播放框架] 0 引言 差不多一个月了,继续分析AOSP的播放框架的源码.这次我们需要深入分析的是N ...
- Laravel开发:Laravel框架门面Facade源码分析
前言 这篇文章我们开始讲 laravel 框架中的门面 Facade,什么是门面呢?官方文档: Facades(读音:/fəˈsäd/ )为应用程序的服务容器中可用的类提供了一个「静态」接口.Lara ...
- Android 应用框架层 SQLite 源码分析
概述 Android 在应用框架层为开发者提供了 SQLite 相关操作接口,其归属于android.database.sqlite包底下,主要包含SQLiteProgram, SQLiteDat ...
随机推荐
- C#入门基础三四
数组:数组是一组具有相同类型的值的集合,可以通过索引来访问数组中的元素. 声明数组的语法: A.数据类型 [] 数组名称: B.数据类型 [] 数组名称 = new 数据类型[数组大小]; C.int ...
- H5常用代码:适配方案4
前面有分享了4种适配方案,但始终是通过手动缩放或者视口缩放来实现,用来做一些专题页,或者功能相对简单的项目来说也是完全能应付的,但整体来说感觉还是一种缩放,说不上是真正的适配,言外之意就是即将分享真正 ...
- Atitit 知识图谱的数据来源
Atitit 知识图谱的数据来源 2. 知识图谱的数据来源1 a) 百科类数据2 b) 结构化数据3 c) 半结构化数据挖掘AVP (垂直站点爬虫)3 d) 通过搜索日志(query record ...
- WebBrowser设置Cookie
在winform里面经常会用到WebBrowser,这是一个难点就是如何设置cookies,注意,Docment对象是只读的,所以WebBrowser.Docment.cookie也就只有get方法, ...
- Servlet Filter
Filter : Java中的Filter 并不是一个标准的Servlet ,它不能处理用户请求,也不能对客户端生成响应. 主要用于对HttpServletRequest 进行预处理,也可以对Http ...
- 如何正确选择UI自动化测试
近年流行一个词-UI,和UI搭边好像都那么高大上,软件测试行业也不例外,比如UI自动化测试. 常见的UI自动化测试程序有哪些呢? l 带UI的Unit Test,比如mock掉底层代码,仅仅测试UI ...
- ASP.NET 如何判断当前请求是否是Ajax请求
/// <summary> /// Description:验证用户是否登陆 /// Author:xucixiao /// Date:2013- ...
- cmder设置打开时的默认目录
cmder设置打开时的默认目录 打开cmder自动进入工作目录,怎么配置? http://superuser.com/questions/1005285/run-a-bat-file-with-cmd ...
- Node学习
参见Node入门 做出node应用的第一个例子 图片上传浏览.
- java中finally和return的执行顺序
注意:return的位置... 从这几个例子中可以看到,如果try之前没有有条件的return,则try..catch..finally语句块中的语句都是顺序执行(如果try中或者catch中 有re ...