项目中用到的设计模式:Reactor设计模式
今天实在百无聊赖的看着代码,实在是没有意思,项目还要等到下个月启动,突然发现项目中的设计模式
挺有趣的,就翻出来看看。
因为我们项目中的结构是客户端-服务端,cs结构的,然后他们之间的通信,是怎么回事情的呢?
以前粗略的看了,主要是通过tcp\ip方式进行通信,但是至少概念中知道吧。今天就翻看一下server代码。
先来了解一下什么是reactor设计模式,反应堆模式。
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;}
这些都是公司大牛写的,真的博大精深,感觉自己要学的东西太多啦。