package com.dronff.one;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* @author tyf
* 2022/5/15
*/
public class Server {
public static void main(String[] args) throws IOException {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.bind(new InetSocketAddress(9888));
Selector selector = Selector.open();
serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);
WorkSelector workSelector = new WorkSelector("work-01");
while (selector.select()>0){
System.out.println("一轮");
Iterator<SelectionKey> selectionKeys = selector.selectedKeys().iterator();
while(selectionKeys.hasNext()){
System.out.println("进入");
SelectionKey selectionKey = selectionKeys.next();
if(selectionKey.isAcceptable()){
//为accept就绪状态
//获取SocketChannel对象
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
workSelector.registry(socketChannel);
}
selectionKeys.remove();
}
}
}
static class WorkSelector implements Runnable{
//是否被初始化过
boolean started = false;
String name;
Selector selector;
ConcurrentLinkedQueue<Runnable> queue = new ConcurrentLinkedQueue<>();
Thread thread;
public WorkSelector(String name){
this.name = name;
}
public void registry(SocketChannel socketChannel) throws IOException {
if(!this.started){
//还没初始化过
//初始化selector
this.selector = Selector.open();
//创建新线程
System.out.println("开始创建新线程");
this.thread = new Thread(this,this.name);
this.thread.start();
System.out.println("创建新线程完成");
}
System.out.println("添加任务中");
this.queue.add(()->{
try {
socketChannel.register(selector,SelectionKey.OP_READ);
} catch (ClosedChannelException e) {
e.printStackTrace();
}
});
System.out.println("添加任务成功");
selector.wakeup();
}
@Override
public void run() {
try {
while (true){
//让worker子线程阻塞在这里,直到主线程调用wakeup方法唤醒它
this.selector.select();
Iterator<SelectionKey> selectionKeys = this.selector.keys().iterator();
Runnable task = queue.poll();
if(task != null){
task.run();
}
while (selectionKeys.hasNext()){
SelectionKey selectionKey = selectionKeys.next();
if(selectionKey.isReadable()){
SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
System.out.print("收到信息:");
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
int len = socketChannel.read(byteBuffer);
System.out.println(new String(byteBuffer.array(),0,len));
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}