1. 程式人生 > >Reactor模式的.net版本簡單實現--DEMO

Reactor模式的.net版本簡單實現--DEMO

pad ring target current orm 抽象基類 分享 public 其他

近期在學習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(0); } public List<Event> Select(int time) {
if(time > 0) { 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 > 0) { 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(1000);
            }
        }
    }

主要職責,對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