近期在学习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的更多相关文章

  1. Reactor 模式的简单实现

    Reactor 模式简单实现 在网上有部分文章在描述Netty时,会提到Reactor.这个Reactor到底是什么呢?为了搞清楚Reactor到底是什么鬼,我写了一个简单的Demo,来帮助大家理解他 ...

  2. ACE - Reactor模式源码剖析及具体实现(大量源码慎入)

    原文出自http://www.cnblogs.com/binchen-china,禁止转载. 在之前的文章中提到过Reactor模式和Preactor模式,现在利用ACE的Reactor来实现一个基于 ...

  3. Reactor模式详解

    转自:http://www.blogjava.net/DLevin/archive/2015/09/02/427045.html 前记 第一次听到Reactor模式是三年前的某个晚上,一个室友突然跑过 ...

  4. IO复用(Reactor模式和Preactor模式)——用epoll来提高服务器并发能力

    上篇线程/进程并发服务器中提到,提高服务器性能在IO层需要关注两个地方,一个是文件描述符处理,一个是线程调度. IO复用是什么?IO即Input/Output,在网络编程中,文件描述符就是一种IO操作 ...

  5. Reactor模式解析——muduo网络库

    最近一段时间阅读了muduo源码,读完的感受有一个感受就是有点乱.当然不是说代码乱,是我可能还没有完全消化和理解.为了更好的学习这个库,还是要来写一些东西促进一下. 我一边读一边尝试在一些地方改用c+ ...

  6. java NIO的多路复用及reactor模式【转载】

    关于java的NIO,以下博客总结的比较详细,适合初学者学习(http://ifeve.com/java-nio-all/) 下面的文字转载自:http://www.blogjava.net/hell ...

  7. C++服务器设计(一):基于I/O复用的Reactor模式

    I/O模型选择 在网络服务端编程中,一个常见的情景是服务器需要判断多个已连接套接字是否可读,如果某个套接字可读,则读取该套接字数据,并进行进一步处理. 在最常用的阻塞式I/O模型中,我们对每个连接套接 ...

  8. Dubbo入门—搭建一个最简单的Demo框架

    一.Dubbo背景和简介 1.电商系统的演进 Dubbo开始于电商系统,因此在这里先从电商系统的演变讲起. a.单一应用框架(ORM) 当网站流量很小时,只需一个应用,将所有功能如下单支付等都部署在一 ...

  9. 也谈Reactor模式

    何谓Reactor模式?它是实现高性能IO的一种设计模式.网上资料有很多,有些写的也很好,但大多不知其所以然.这里博主按自己的思路简单介绍下,有不对的地方敬请指正. BIO Java1.4(2002年 ...

随机推荐

  1. Android 内核常见目录的作用

    / :根目录 /bin目录 :命令保存目录,普通用户就可以读取的命令. /boot目录 :启动目录,启动相关文件 /dev :设备文件保存目录 /etc :配置文件保存目录 /home :普通用户的家 ...

  2. Android Camera开发系列(上)——Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片

    Android Camera开发系列(上)--Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片 最近也是在搞个破相机,兼容性那叫一个不忍直视啊,于是自己翻阅了一些基本的资料,自己实现了一 ...

  3. LAV Filter 源代码分析 3: LAV Video (1)

    LAV Video 是使用很广泛的DirectShow Filter.它封装了FFMPEG中的libavcodec,支持十分广泛的视频格式的解码.在这里对其源代码进行详细的分析. LAV Video ...

  4. NOSQL schema创建原则

    (1)数据规模 Bigtable类数据库系统(HBase,Cassandra等)是为了解决海量数据规模的存储需要设计的.这里说的海量数据规模指的是单个表存储的数据量是在TB或者PB规模,单个表是由千亿 ...

  5. The 13th tip of DB Query Analyzer, powerful processing EXCEL file

    The 13thtip of DB Query Analyzer, powerful processing EXCEL file MA Genfeng (Guangdong UnitollServic ...

  6. Mac OS X 简单的方法知道何时来电了

    最近本猫所在的小区时常停电,往往半夜或是凌晨才来电啊!早上起来本猫在想如何知道确切的来电时间,但又不费事的方法呢. 方法一是用手机录音器录音,因为来电后门禁会发出"滴"的一声,所以 ...

  7. caffe中是如何运用protobuf构建神经网络的?

    caffe这个框架设计的比较小巧精妙,它采用了protobuf来作为交互的媒介,避免了繁重的去设计各个语言的接口,开发者可以使用任意语言通过这个protobuf这个媒介,来运行这个框架. 我们这里不过 ...

  8. 2018 ACM-ICPC World Finals B.Comma Sprinkler

    WF里面最简答一题,就是一个dfs就可以了,已经访问过的点可以不再访问 #include <algorithm> #include <cmath> #include <c ...

  9. Jquery的过滤选择器分为哪几种?

    Jquery的过滤选择器分为哪几种? 转载▼ 标签: jquery 过滤选择器 分类 分类: JQuery 所有的过滤选择器分为哪几种: 一.基本过滤选择器(重点掌握下列八个) :first 选取第一 ...

  10. ORACLE之TO_DATE (转载)

    转自 http://www.cnblogs.com/anran_guojianjun/archive/2009/09/11/1564535.html 一.在使用Oracle的to_date函数来做日期 ...