React模式在Nio中的实现

本文介绍了一个基于Netty的Reactor模式实现案例,该案例详细展示了如何使用Java NIO来创建一个非阻塞的聊天服务器。通过将事件处理逻辑与I/O操作分离,实现了高效并发的服务端应用。
package com.roc.netty.NettyChat;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * 关键在于通过注册channel到selector后返回的key上附加相应的处理器,用来分别处理不同的事件
 * @author Administrator
 *
 */
/**
 * 这个React就相当于Initiation Dispatcher
 * 循环,得到事件,并将事件分发出去
 * @author Administrator
 *
 */
public class Reactor implements Runnable{

	private static ServerSocketChannel serverSocketChannel;
	private static Selector selector;
	public void run() {
		// TODO Auto-generated method stub
		try {
			serverSocketChannel = ServerSocketChannel.open();
			selector = Selector.open();
			serverSocketChannel.configureBlocking(false);
			serverSocketChannel.bind(new InetSocketAddress(8899));
			SelectionKey selectionKey = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
			selectionKey.attach(new Acceptor(selector,selectionKey));
			System.out.println("系统服务启动。。。。");
			while(true){
				selector.select();
				Set<SelectionKey> keys =  selector.selectedKeys();
				for(SelectionKey key :keys){
					//分发事件
					dispatch(key);
					keys.remove(key);
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	//分发事件
	private void dispatch(SelectionKey key){
		Runnable acceptor = (Runnable)key.attachment();
		acceptor.run();
	}
	//对应的接收连接事件处理器
	class Acceptor implements Runnable{
		Selector selector;
		SelectionKey selectionKey;
		
		public Acceptor(Selector selector, SelectionKey selectionKey) {
			this.selector = selector;
			this.selectionKey = selectionKey;
		}

		public void run() {
			// TODO Auto-generated method stub
			System.out.println("连接进入。。。。");
			try {
				ServerSocketChannel serverSocketChannel = (ServerSocketChannel)selectionKey.channel();
				SocketChannel socketChannel = serverSocketChannel.accept();
				socketChannel.configureBlocking(false);
				SelectionKey key = socketChannel.register(selector, SelectionKey.OP_READ);
				key.attach(new ReadHandler(key,selector));
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}
	//对应的读事件的处理器
	class ReadHandler implements Runnable{
		SelectionKey selectionKey;
		Selector selector;
		public ReadHandler(SelectionKey selectionKey, Selector selector) {
			this.selectionKey = selectionKey;
			this.selector = selector;
		}
		public void run() {
			System.out.println("读入数据。。。");
			SocketChannel socketChannel = (SocketChannel)selectionKey.channel();
			ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
			try {
				socketChannel.read(byteBuffer);
				byteBuffer.flip();
				File file = new File("C:/Users/Administrator/Desktop/aa.txt");
				FileOutputStream fileOutputStream = new FileOutputStream(file);
				FileChannel fileChannel = fileOutputStream.getChannel();
				fileChannel.write(byteBuffer);
				fileOutputStream.close();
				System.out.println("完成数据。。。");
				//byteBuffer.flip();
				//socketChannel.write(byteBuffer);
				//selector.wakeup();  
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	
	public static void main(String[] args) {
		Reactor reactor = new Reactor();
		ExecutorService executorService = Executors.newSingleThreadExecutor();
		executorService.submit(reactor);
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值