All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.banny.rp.io.NIOSocketSessionDispatcher Maven / Gradle / Ivy

The newest version!
package cn.banny.rp.io;

import cn.banny.rp.ReverseProxy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.EOFException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

/**
 * @author zhkl0228
 *
 */
public class NIOSocketSessionDispatcher {
	
	private static final Logger log = LoggerFactory.getLogger(NIOSocketSessionDispatcher.class);
	
	private final ByteBuffer readBuffer;

	public NIOSocketSessionDispatcher(ByteBuffer readBuffer) {
		super();
		this.readBuffer = readBuffer;
	}

	public void dispatch(Set keys) {
		try {
			processSelectionKeys(keys.iterator());
		} finally {
			keys.clear();
		}
	}

	private void processSelectionKeys(Iterator selectionKeys) {
		while(selectionKeys.hasNext()) {
			SelectionKey key = selectionKeys.next();
			SelectableChannel channel = key.channel();
			NIOSocketSession session = (NIOSocketSession) key.attachment();
			
			try {
				if(!key.isValid()) {
					continue;
				}

				if(key.isConnectable()) {
					session.processConnect((SocketChannel) channel);
				}
				if(key.isWritable()) {
					session.processWrite((SocketChannel) channel, key);
				}
				if(key.isReadable()) {
					// System.out.println("key=" + key + ", channel=" + channel);
					processRead((SocketChannel) channel, session, key);
				}
				if(channel instanceof ServerSocketChannel && key.isAcceptable()) {
					session.processAccept((ServerSocketChannel) channel);
				}
			} catch(EOFException e) {
				key.cancel();
				session.processException(channel, e);
			} catch(IOException e) {
				key.cancel();
				ReverseProxy.closeQuietly(channel);
				session.processException(channel, e);
				session.notifyClosed(channel);
			} catch(Throwable e) {
				if(log.isDebugEnabled()) {
					log.debug(e.getMessage(), e);
				}
				key.cancel();
				ReverseProxy.closeQuietly(channel);
				session.notifyClosed(channel);
			} finally {
				selectionKeys.remove();
			}
		}
	}

	private void processRead(SocketChannel channel,
			NIOSocketSession session, SelectionKey key) throws IOException {
		int read;
		do {
			readBuffer.clear();
			read = channel.read(readBuffer);
			if(read == -1) {
				throw new EOFException();
			}
			if(read < 1) {
				break;
			}
			
			readBuffer.flip();
			session.processRead(channel, readBuffer, key);
		} while(true);
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy