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

io.craft.atom.nio.NioConnector Maven / Gradle / Ivy

There is a newer version: 3.1.2
Show newest version
package io.craft.atom.nio;

import io.craft.atom.io.Channel;
import io.craft.atom.io.IoConnector;
import io.craft.atom.io.IoConnectorX;
import io.craft.atom.io.IoHandler;
import io.craft.atom.io.IoReactorX;
import io.craft.atom.nio.api.NioConnectorConfig;
import io.craft.atom.nio.spi.NioBufferSizePredictorFactory;
import io.craft.atom.nio.spi.NioChannelEventDispatcher;
import io.craft.atom.util.thread.NamedThreadFactory;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.channels.Selector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import lombok.ToString;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Connects to server based on TCP or UDP, communicates with the server, and fires events.
 * 
 * @author mindwind
 * @version 1.0, Feb 24, 2013
 * @see NioTcpConnector
 */
@ToString(callSuper = true, of = { "config" })
abstract public class NioConnector extends NioReactor implements IoConnector {
	
	
	private static final Logger LOG = LoggerFactory.getLogger(NioConnector.class);
	
	
	protected final    NioConnectorConfig config                                                                                             ;                                                                                          ;                                                                                             ;
	protected final    ExecutorService    executorService = Executors.newCachedThreadPool(new NamedThreadFactory("craft-atom-nio-connector"));
	protected volatile boolean            selectable      = false                                                                            ;
	protected volatile boolean            shutdown        = false                                                                            ;
	protected volatile Selector           selector                                                                                           ;
	
	
	// ~ ------------------------------------------------------------------------------------------------------------
	
	
	/**
	 * Constructs a new connector with default configuration.
	 *  
	 * @param handler
	 */
	public NioConnector(IoHandler handler) {
		this(handler, new NioConnectorConfig());
	}
	
	/**
	 * Constructs a new connector with the specified configuration.
	 *  
	 * @param handler
	 * @param config
	 */
	public NioConnector(IoHandler handler, NioConnectorConfig config) {
		this(handler, config, new NioOrderedDirectChannelEventDispatcher(config.getTotalEventSize()), new NioAdaptiveBufferSizePredictorFactory());
	}
	
	/**
	 * Constructs a new connector with the specified configuration and dispatcher.
	 * 
	 * @param handler
	 * @param config
	 * @param dispatcher
	 */
	public NioConnector(IoHandler handler, NioConnectorConfig config, NioChannelEventDispatcher dispatcher) {
		this(handler, config, dispatcher, new NioAdaptiveBufferSizePredictorFactory());
	}
	
	/**
	 * Constructs a new connector with the specified configuration, dispatcher and predictor.
	 * 
	 * @param handler
	 * @param config
	 * @param dispatcher
	 * @param predictorFactory
	 */
	public NioConnector(IoHandler handler, NioConnectorConfig config, NioChannelEventDispatcher dispatcher, NioBufferSizePredictorFactory predictorFactory) {
		if (handler == null) {
			throw new IllegalArgumentException("Handler should not be null!");
		}
		
		this.config = (config == null ? new NioConnectorConfig() : config);
		this.handler = handler;
		this.dispatcher = dispatcher;
		this.predictorFactory = predictorFactory;
		this.pool = new NioProcessorPool(config, handler, dispatcher);
		try {
			init();
		} catch (IOException e) {
			throw new RuntimeException("Failed to construct.", e);
		} finally {
			if (!selectable && selector != null) {
				try {
					selector.close();
				} catch (IOException e) {
					LOG.warn("[CRAFT-ATOM-NIO] Close selector exception", e);
				}
			}
		}
	}
	
	
	// ~ ------------------------------------------------------------------------------------------------------------
	
	
	private void init() throws IOException {
		selector = Selector.open();
		selectable = true;
	}
	
	@Override
	public Future> connect(String ip, int port) throws IOException {
		SocketAddress remoteAddress = new InetSocketAddress(ip, port);
		return connect(remoteAddress);
	}
	
	@Override
	public Future> connect(SocketAddress remoteAddress) throws IOException {
        return connect(remoteAddress, null);
    }
	
	@Override
	public Future> connect(SocketAddress remoteAddress, SocketAddress localAddress) throws IOException {
		if (!this.selectable) {
			throw new IllegalStateException("The connector is already shutdown.");
		}

		if (remoteAddress == null) {
			throw new IllegalArgumentException("Remote address is null.");
		}
		
		if (handler == null) {
			throw new IllegalStateException("Handler is not be set!");
		}
		
		return connectByProtocol(remoteAddress, localAddress);
	}
	
	@Override
	public void shutdown() {
		this.selectable = false;
		this.shutdown = true;
		this.selector.wakeup();
	}
	
	@Override
	public IoConnectorX x() {
		NioConnectorX x = new NioConnectorX();
		IoReactorX rx = super.x();
		x.setNewChannelCount(rx.newChannelCount());
		x.setFlushingChannelCount(rx.flushingChannelCount());
		x.setClosingChannelCount(rx.closingChannelCount());
		x.setAliveChannelCount(rx.aliveChannelCount());
		xByProtocol(x);
		return x;
	}
	
	abstract protected Future> connectByProtocol(SocketAddress remoteAddress, SocketAddress localAddress) throws IOException;
	abstract protected void xByProtocol(NioConnectorX x);
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy