反应器模式,是使用java io多路复用技术
两大角色:反应器线程;handler处理器
反应器线程:负责响应IO事件,并且分发到handler处理器
handler处理器:执行业务处理逻辑
示例代码可以直接使用
Reactor
public class Reactor implements Runnable{
//选择器
Selector selector;
//io通道
ServerSocketChannel serverSocket;
public Reactor() throws Exception{
//打开选择器
selector = Selector.open();
//获取通道
serverSocket = ServerSocketChannel.open();
InetSocketAddress adress = new InetSocketAddress("127.0.0.1",8081);
serverSocket.socket().bind(adress);
serverSocket.configureBlocking(false);
//注册serverSocket的accept事件
SelectionKey sk = serverSocket.register(selector, SelectionKey.OP_ACCEPT);
//向选择健中增加一个对象
sk.attach(new AcceptorHandler());
}
@Override
public void run() {
//轮询选择器
try {
while(!Thread.interrupted()){
selector.select();
Set selected = selector.selectedKeys();
Iterator it = selected.iterator();
while(it.hasNext()){
//反应器负责分发操作
SelectionKey sk = (SelectionKey) it.next();
dispatch(sk);
}
//清空取到对象列表
selected.clear();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//反应器分发 handle
public void dispatch(SelectionKey sk){
//获取开始添加的对象 new AcceptorHandler()
Runnable handler = (Runnable)(sk.attachment());
if(handler!=null){
handler.run();
}
}
//新建连接处理器
class AcceptorHandler implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
try {
SocketChannel sc = serverSocket.accept();
if(sc!=null){
//将接收到信息信息 IOHandler 进行处理
new IOHandler(selector,sc);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
**IOHandler**
```java
public class IOHandler implements Runnable {
final SocketChannel channel;
final SelectionKey sk;
final ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
static final int RECIVING=0,SENDING=1;
int state =RECIVING;
IOHandler(Selector selector,SocketChannel c) throws IOException{
channel = c;
c.configureBlocking(false);
//仅仅获取选择键,稍后设置感兴趣的IO事件
sk = channel.register(selector, 0);
//将handler处理器作为选择键的附件
sk.attach(this);
//注册读写就绪事件
sk.interestOps(SelectionKey.OP_READ);
selector.wakeup();
}
@Override
public void run() {
//处理输入输出
try {
Thread.sleep(1000);
if(state == SENDING){
channel.write(byteBuffer);
byteBuffer.clear();
sk.interestOps(SelectionKey.OP_READ);
state = RECIVING;
}else if(state ==RECIVING){
int len = 0;
while((len=channel.read(byteBuffer))>0){
System.out.println(new String(byteBuffer.array(),0,len));
}
byteBuffer.flip();
sk.interestOps(SelectionKey.OP_WRITE);
state = SENDING;
}
//处理结束
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
**客户端ReactorClient**`
`public class ReactorClient {
public static void startClient() throws Exception{
//设置 SocketChannel
InetSocketAddress adress = new InetSocketAddress("127.0.0.1",8081);
SocketChannel socket = SocketChannel.open(adress);
socket.configureBlocking(false);
//连接
while(!socket.finishConnect()){
}
System.out.println("客户端连接成功");
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
byteBuffer.put("HELLO WORLD".getBytes());
byteBuffer.flip();
socket.write(byteBuffer);
socket.shutdownInput();
socket.close();
}
}