Reactor模式的.net版本简单实现--DEMO
近期在学习DotNetty,遇到不少的问题。由于dotnetty是次netty的.net版本的实现。导致在网上叙述dotnetty的原理,以及实现技巧方面的东西较少,这还是十分恼人的。在此建议学习和使用Dotnetty的和位小伙伴,真心阅读下netty的相关书籍,如《netty权威指南》。
闲话少说,进入正题。netty的性能之所以能够达到如此的高度。主要由于他使用Reactor模式处理socket的请求,让服务器的使用率最大化,且尽量减少线程的开销。本文章主要简单介绍下Reactor模式。
一、reactor概论
reactor模式主要解决处理多个客户端请求的设计模式。

首先从类图我们可以得知:
Dispatcher:Handler管理器,以及调用度。他依赖于Demultiplexer类
Demultiplexer:事件管理器,接受外部的事件,并提供给Dispatch使用。
Handle:事件源,表示触发了那些事件
EventHandler:各种类型的处理器,用于处理具体的业务,以及I/O的读写
当然,也可以通过序列图看出首先需要初始化Dispatcher, Demultiplexer等相关类,以及注册具体的事件处理器。
二、代码的具体实现
类图如下[源码下载]:

2.1 多路复用事件处理器的代码
public class Demultiplexer
{
private ConcurrentQueue<Event> eventQuene = new ConcurrentQueue<Event>();
private Object lockObj = new Object(); public List<Event> Select()
{
return this.Select();
}
public List<Event> Select(int time)
{
if(time > )
{
if (this.eventQuene.IsEmpty)
{
lock (lockObj)
{
if (this.eventQuene.IsEmpty)
{
System.Threading.Thread.Sleep(time);
}
}
}
}
List<Event> events = new List<Event>();
while(this.eventQuene.Count > )
{
Event tmp;
if(this.eventQuene.TryDequeue(out tmp))
{
events.Add(tmp);
}
}
return events;
}
public void AddEvent(Event argEvent)
{
this.eventQuene.Enqueue(argEvent);
}
}
此类主要防止多线程的共同竞争,因为多路径复用选择器会被多个线程同时使用。所以使用的线程安全的Queue。
2.2 Handler触发器和管理器
/// <summary>
/// Reactor的事件Handler触发器,提供事件Handler的注册,移除
/// </summary>
public class EventDispatch
{
private Demultiplexer demultiplexer;
Dictionary<EventType, EventHandler> eventHandlerMap = new Dictionary<EventType, EventHandler>(); public EventDispatch(Demultiplexer demultiplexer)
{
this.demultiplexer = demultiplexer;
} public void RegisterHandler(EventType eventType, EventHandler eventHandler)
{
this.eventHandlerMap.Add(eventType, eventHandler);
}
public void RemoveHandler(EventType eventType)
{
this.eventHandlerMap.Remove(eventType);
} public void HandleEvents()
{
this.Dispatch();
}
public void Dispatch()
{
string log = string.Format("thread id: {0} Dispatch", System.Threading.Thread.CurrentThread.ManagedThreadId);
Console.WriteLine(log);
while (true)
{
List<Event> events = this.demultiplexer.Select();
foreach(var itemEvent in events)
{
EventHandler eventHandler = this.eventHandlerMap[itemEvent.EventType];
eventHandler.Handle(itemEvent);
}
System.Threading.Thread.Sleep();
}
}
}
主要职责,对Handler的注册、移除的管理,以及通过 多路复用选择器 选择相应的Handler进行处理。
2.3 服务端的实现
/// <summary>
/// 开启接受请求的服务端
/// </summary>
public class AcceptRuner
{
private System.Collections.Concurrent.ConcurrentQueue<object> sourceQueue = new System.Collections.Concurrent.ConcurrentQueue<object>(); private Demultiplexer demultiplexer; public AcceptRuner(Demultiplexer demultiplexer)
{
this.demultiplexer = demultiplexer;
} public void adConnection(object source)
{
this.sourceQueue.Enqueue(source);
} public void Run()
{
string log = string.Format("thread id: {0} AcceptRunner", System.Threading.Thread.CurrentThread.ManagedThreadId);
Console.WriteLine(log);
while (true)
{
object source;
if(this.sourceQueue.TryDequeue(out source))
{
Event acceptEvent = new Event()
{
EventType = EventType.Accept,
Source = source
};
this.demultiplexer.AddEvent(acceptEvent);
}
}
}
}
此类效仿netty的serverBoostrap的实现,将外部新的连接以事件对象的形式添加到 多路复用选择器上。
2.4 其他类
Event:事件基类
EventHandler:事件处理器抽象基类。他派生了:AcceptEventHandler,ReadEventHandler。
EventType:事件类型
三、备注说明
1. 代码没有贴完整。但下载包就是完整的。
2. 这只我对Reactor模式的理解,如有偏颇之处,还望各拉指点一二。
Reactor模式的.net版本简单实现--DEMO的更多相关文章
- Reactor 模式的简单实现
Reactor 模式简单实现 在网上有部分文章在描述Netty时,会提到Reactor.这个Reactor到底是什么呢?为了搞清楚Reactor到底是什么鬼,我写了一个简单的Demo,来帮助大家理解他 ...
- ACE - Reactor模式源码剖析及具体实现(大量源码慎入)
原文出自http://www.cnblogs.com/binchen-china,禁止转载. 在之前的文章中提到过Reactor模式和Preactor模式,现在利用ACE的Reactor来实现一个基于 ...
- Reactor模式详解
转自:http://www.blogjava.net/DLevin/archive/2015/09/02/427045.html 前记 第一次听到Reactor模式是三年前的某个晚上,一个室友突然跑过 ...
- IO复用(Reactor模式和Preactor模式)——用epoll来提高服务器并发能力
上篇线程/进程并发服务器中提到,提高服务器性能在IO层需要关注两个地方,一个是文件描述符处理,一个是线程调度. IO复用是什么?IO即Input/Output,在网络编程中,文件描述符就是一种IO操作 ...
- Reactor模式解析——muduo网络库
最近一段时间阅读了muduo源码,读完的感受有一个感受就是有点乱.当然不是说代码乱,是我可能还没有完全消化和理解.为了更好的学习这个库,还是要来写一些东西促进一下. 我一边读一边尝试在一些地方改用c+ ...
- java NIO的多路复用及reactor模式【转载】
关于java的NIO,以下博客总结的比较详细,适合初学者学习(http://ifeve.com/java-nio-all/) 下面的文字转载自:http://www.blogjava.net/hell ...
- C++服务器设计(一):基于I/O复用的Reactor模式
I/O模型选择 在网络服务端编程中,一个常见的情景是服务器需要判断多个已连接套接字是否可读,如果某个套接字可读,则读取该套接字数据,并进行进一步处理. 在最常用的阻塞式I/O模型中,我们对每个连接套接 ...
- Dubbo入门—搭建一个最简单的Demo框架
一.Dubbo背景和简介 1.电商系统的演进 Dubbo开始于电商系统,因此在这里先从电商系统的演变讲起. a.单一应用框架(ORM) 当网站流量很小时,只需一个应用,将所有功能如下单支付等都部署在一 ...
- 也谈Reactor模式
何谓Reactor模式?它是实现高性能IO的一种设计模式.网上资料有很多,有些写的也很好,但大多不知其所以然.这里博主按自己的思路简单介绍下,有不对的地方敬请指正. BIO Java1.4(2002年 ...
随机推荐
- PS 滤镜——素描算法(一)
这个算法结合高斯滤波和图层混合中的颜色减淡模式实现. 可以参考相关博客: http://blog.csdn.net/wsfdl/article/details/7610634 本文增加了一点调色,使得 ...
- 关于L298N的应用
最近在开发一个基于STM32的智能小车,用的底板是野火ISO mini的板子.如图: 这里有个电机驱动模块L298N,说起它,我还真的泪奔,前阵子被卖家坑了,拿上去一接电源马上就烧了,这都怪我粗心大意 ...
- iOS监听模式系列之关于delegate(代理,委托)的学习
首先,大家应该都明白的是委托是协议的一种,顾名思义,就是委托他人帮自己去做什么事.也就是当自己做什么事情不方便的时候,就可以建立一个委托,这样就可以委托他人帮自己去实现什么方法. 其次,我简单的总结了 ...
- LeetCode(30)-Pascal's Triangle
题目: Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5, ...
- solr研磨之游标分页
普通分页 当需要深度分页的时候,比如查询第10000页数据,每页显示10条,意味着需要提取前10000 x 10 页的数据,并将这100000条数据缓存在内存中,然后在内存中进行排序.最后返回最后10 ...
- maven常见配置
maven surefire plugin 默认执行失败后,不会继续执行,需要在</configuration>中设置参数 <testFailureIgnore>true< ...
- 如何实现Zabbix的主动注册功能
主动注册(Active Agent Auto-Registration),顾名思义,无需在Zabbix Web上手动添加host信息,即可实现主机的监控. 它是由Agent主动向Server注册. 相 ...
- IT桔子沙龙之本地生活服务O2O探路者笔记整理
这个沙龙活动侧重于创业融资与投资角度 主持人:真格基金投资分析师顾女士;E-mail:grace@zhenfund.com;新浪微博:@顾三小姐 赞助商七牛云的服务宣传:静态资源托管:上传下载全网加速 ...
- PyQt IDE 环境搭建
Eric的安装 1.按照目前pyqt5的要求安装了python3的最新版 2 pip3 install PyQt5 3. pip3 install QScintilla 4.download eric ...
- Java并发编程——BlockingQueue
简介 BlockingQueue很好的解决了多线程中,如何高效安全"传输"数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利. 阻塞队列是 ...