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年 ...
随机推荐
- LeetCode之“数学”:Plus One
题目链接 题目要求: Given a non-negative number represented as an array of digits, plus one to the number. Th ...
- Linux - gcc 的简易用法 (编译、参数与链结)
# 仅将原始码编译成为目标档,并不制作连结等功能: [root@www ~]# gcc -c hello.c # 会自动的产生 hello.o 这个文件,但是并不会产生 binary 运行档. # 在 ...
- OpenGL OpenCV根据视差图重建三维信息
代码如下: // disparity_to_3d_reconstruction.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" //Huan ...
- Paxos 算法
1 概述 Paxos算法是莱斯利·兰伯特(Leslie Lamport,就是 LaTeX 中的"La",此人现在在微软研究院)于1990年提出的一种基于消息传递的一致性算法.[1] ...
- LeetCode(43)-Contains Duplicate II
题目: Given an array of integers and an integer k, find out whether there are two distinct indices i a ...
- 在Eclipse 中集成SVN
在项目开发的过程中,我们需要用到版本控制工具,最常见的也就是SVN了,下面就来介绍最简单的一种在Elipse中集成svn工具. 第一步:下载 svn包,如site-1.6.5.zip或者site-1. ...
- Cocoa编程之IBAction和IBOutlet含义
IBAction / IBOutlet / IBOutletCollection 时间 2014-05-05 15:00:00 NSHipster原文 http://nshipster.com/i ...
- Eclipse的优化
1. 取消系统的自动折叠 Window->Preferences-> Java->Editor->Folding: Enable folding 2. 取消按".&q ...
- 三种Tomcat集群方式的优缺点分析
三种Tomcat集群方式的优缺点分析 2009-09-01 10:00 kit_lo kit_lo的博客 字号:T | T 本文对三种Tomcat集群方式的优缺点进行了分析.三种集群方式分别是:使用D ...
- QQ connect client request's parameters are invalid, invalid openid 问题的解决
很多人的这个问题是POST的时候发生,我的也恰好在POST的时候发生.后来我发现可能是因为QQ的这个后端是采用类PHP的语言开发,在动态语言的获取参数时POST参数和GET参数是可以分开读取的,也就是 ...