Package com.yz.net.impl

Source Code of com.yz.net.impl.IoServerImpl

package com.yz.net.impl;


import java.io.IOException;
import java.net.ServerSocket;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import com.yz.net.ProtocolHandler;



/**
* <p>
* 用于构建服务器的具体实现类,实现类屏蔽了许多可以灵活设置的方法,比如设置IO处理线程的设置,而这个在扩展的IoConnector<br>
* 中却又开放了,是因为我们认为服务器的IO处理线程是和实现的CPU个数挂勾的,我们认为要允份利用CPU资源每一个CPU可以利用一<br>
* 线程,所以这里屏蔽是不想让使用者有更多的选择而感到不知所挫,
*
*
* 关于IoConnector开发的原因:
* 而IoConnector之所以开放,是因为IoConnector只是框架的一个扩展,是用于构建客户端应用的,最初的设想是让他构建代理服务器的<br>
* ,不过后来经过大家的讨论,希望让框架能有客户端的支撑,所以在不修改原来的框架前提下开放IO处理线程的设置,这样可以方便的用<br>
* 于构建代理服务器,与客户端应用。
* </p>
* <br>
* @author 胡玮@ritsky
*
*/
public class IoServerImpl extends AbstractIoService implements Runnable{
 
  /**服务器监听Socket*/
  private ServerSocketChannel ssChannel;
 
  /**选择器*/
  private Selector selector;
 
  private boolean isRunning;
 
  private static final int CPU_NUM = Runtime.getRuntime().availableProcessors();
 
  public IoServerImpl() throws Exception{
    super();
    this.initIoReadWriteMachines(CPU_NUM);   //实始化读写机
  }

 
  @Override
  public void start() throws Exception {
    super.start();
    startTimer();              //启动定时器
   
    if(this.getConfigure().getAddress() == null) {
      throw new Exception("没有绑定地址");
    }
   
   
 
    selector = Selector.open();         //打开选择器
   
    ssChannel = ServerSocketChannel.open();
    ssChannel.configureBlocking(false);       //设定为非阻塞
    ServerSocket ss = ssChannel.socket();
    ss.bind(this.getConfigure().getAddress());
   
       
    ssChannel.register(selector, SelectionKey.OP_ACCEPT);
   
    this.startIoReadWriteMachines();
   
    Thread t = new Thread(this, "IoAcceptor");
    t.start();
   
    this.isStart = true;
  }
 
 
 
 
  public void stop() {
    synchronized (stopLock) {
      if(this.isRunning) {
        this.isStart = false;
        this.isRunning = false;
        this.selector.wakeup();
        getTimer().cancel();
       
        this.closeAllSession(); //一但调和就产生阻塞,只到所有会话关闭为止
        stopIoReadWriteMachines();
       
        try {
          this.selector.close();
          this.ssChannel.close();
        } catch (IOException e) {}
      }
    }
  }
 
 
 
 

  @Override
  public void run() {
   
    isRunning = true;
      while(isRunning){
       
        try {
        selector.select();
      } catch (IOException e) {
        //TODO:记录下异常
        e.printStackTrace();
      }
       
        for(Iterator<SelectionKey> i = selector.selectedKeys().iterator(); i.hasNext();) {
          SelectionKey sk = i.next();
          i.remove();
         
          if(sk.isValid() == false) {
            //TODO:考虑是否抛出异常
          }
         
          if(sk.isAcceptable()) {
           
            SocketChannel sc = null;
            try {
            sc = this.ssChannel.accept();
            sc.configureBlocking(false);
          } catch (IOException e) {
            //TODO:记录下此异常
            e.printStackTrace();
          }
         
          if(sc == null) {
            continue;
          }
         
         
          IoSessionImpl session = newIoSession(sc);
          scheduleToDispatcher(session);   //在一个发报机中排程注册
          }
        }
      } 
  }

 
  /**
   * 产生一个新的IoSession
   * @param sc
   * @return
   */
  private IoSessionImpl newIoSession(SocketChannel sc) {
    long id = getNextSessionId();
   
    IoSessionImpl session = new IoSessionImpl(id, sc, this);
    return session;
  }

}
TOP

Related Classes of com.yz.net.impl.IoServerImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.