项目中用到的设计模式:Reactor设计模式

来源:互联网 发布:it服务管理平台 编辑:程序博客网 时间:2024/06/09 19:50

    今天实在百无聊赖的看着代码,实在是没有意思,项目还要等到下个月启动,突然发现项目中的设计模式

挺有趣的,就翻出来看看。


     因为我们项目中的结构是客户端-服务端,cs结构的,然后他们之间的通信,是怎么回事情的呢?

以前粗略的看了,主要是通过tcp\ip方式进行通信,但是至少概念中知道吧。今天就翻看一下server代码。


先来了解一下什么是reactor设计模式,反应堆模式。


高性能I/O设计模式 - Reactor

 该设计模式用于派发/分离IO操作事件的,这里所谓的IO事件也就是诸如read/write 的IO操作,“派发\分离”就是将单独的IO事件通知到上层模块,Reactor用于同步IO。


Reactor设计模式中的要素如下:
Handles,也就是网络连接,文件句柄等。是事件源。
Synchronous Event Demultiplexer,同步事件的解复用(或者说派发),具体的比如select调用。比select更加高效的有linux下的epoll,freebsd下的kqueue以及windows下的iocp(IO Completion port)。
Initiation Dispatcher,注册、移除和分派事件处理句柄。
Event Handler,就是事件处理句柄。


结合上面的描述,给出来自参考资料[3]图片如下:


                    



下面这个是项目中的类图:



1.reactor  负责响应IO事件,一旦发生,广播到响应的TcpThreadPool,TcpThreadPool发送给响应的IHandleEvent实现类去处理。


2. handler是非阻塞行为,同时负责将handlers与event事件绑定。


这里是refactor的handEvent方法;



public int handleEvent(long wtime){PendingObj handler = null;while ( (handler = _pendingQueue.pop()) != null){ if (handler.handler == null) continue;switch (handler.type){case ACP_TYPE:try{initServerChannel(handler);}catch (Exception e){Debug.logOut(Debug.ERROR, this, e);}break;case CON_TYPE:try{initClientChannel(handler);}catch (Exception e){Debug.logOut(Debug.ERROR, this, e);}break;default:try{updateSelectCol(handler);}catch (Exception e){Debug.msg(Debug.ERROR, "updateSelectCol occur exception:", e.getMessage());Debug.logOut(Debug.ERROR, this, e);}  break;}}//long cur = System.currentTimeMillis();//long to = timequeue.earliestTime();//long cal = to - cur;//if (wtime > cal)//wtime = cal;int num;this.wakenUp.set(false);try{if (wtime <= 0)num = selector.selectNow();  // no here, and not permit walking here, or else cpu 100%elsenum = selector.select(wtime);}catch (Exception e){Debug.msg(Debug.ERROR, "selector occur exception:" , e.getMessage());Debug.logOut(Debug.ERROR, this, e);return -1;}//timequeue.dispatchHandlers();if (num <= 0) return num;try{Iterator iterator = selector.selectedKeys().iterator();while (iterator.hasNext()){SelectionKey key = (SelectionKey) iterator.next();iterator.remove();IHandleEvent handlers = (IHandleEvent) key.attachment();int r1 = 0;if (! key.isValid()) continue;else if (key.isAcceptable())  // for server{r1 = handlers.handleAccept();}else if (key.isConnectable()) // 处理前一定要禁止任何操作{key.interestOps(key.interestOps() & ~key.readyOps());r1 = handlers.handleConnect();}else if (key.isReadable()){do{r1 = handlers.handleInput();} while (r1 > 0);}else if (key.isWritable()){if (pool != null ){TcpWorker worker = null;if (((TCPLink)handlers).isBusy) continue;else if ((worker = pool.getIdleWorker()) == null){try{Thread.sleep(1000);}catch (InterruptedException e){Debug.msg(Debug.ERROR, this , e.getMessage());Thread.interrupted();}_pendingQueue.put(new PendingObj(handlers, SelectionKey.OP_WRITE, ADD_TYPE ));}else worker.setHandler(handlers);continue ;}int count = 0;do{r1 = handlers.handleOutput(); count++;if (count > 3) break; } while (r1 > 0); //连续写,r1为0时发送队列数据为空;here将来可考虑多线程}if (r1 < 0){unregister(handlers, true);}}}catch (Exception e){Debug.msg(Debug.ERROR, "SelectionKey occur runtime exception:", e.getMessage());Debug.logOut(Debug.ERROR, this, e);return -1;}return num;}



这些都是公司大牛写的,真的博大精深,感觉自己要学的东西太多啦。




原创粉丝点击