com.github.ltsopensource.nio.channel.NioChannelImpl Maven / Gradle / Ivy
package com.github.ltsopensource.nio.channel;
import com.github.ltsopensource.core.logger.Logger;
import com.github.ltsopensource.core.logger.LoggerFactory;
import com.github.ltsopensource.nio.codec.Decoder;
import com.github.ltsopensource.nio.codec.Encoder;
import com.github.ltsopensource.nio.config.NioConfig;
import com.github.ltsopensource.nio.handler.Futures;
import com.github.ltsopensource.nio.handler.NioHandler;
import com.github.ltsopensource.nio.idle.IdleInfo;
import com.github.ltsopensource.nio.idle.IdleState;
import com.github.ltsopensource.nio.loop.NioSelectorLoop;
import com.github.ltsopensource.nio.processor.NioProcessor;
import io.netty.util.internal.ThreadLocalRandom;
import java.io.IOException;
import java.net.SocketAddress;
import java.nio.channels.SelectableChannel;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author Robert HG ([email protected]) on 1/24/16.
*/
public class NioChannelImpl implements NioChannel {
private static final Logger LOGGER = LoggerFactory.getLogger(NioChannelImpl.class);
private final long id;
private static final AtomicInteger CONN_ID = new AtomicInteger(0);
private NioProcessor processor;
private NioSelectorLoop selectorLoop;
protected Futures.CloseFuture closeFuture = Futures.newCloseFuture();
private IdleInfo idleInfo;
private NioConfig config;
private Decoder decoder;
private Encoder encoder;
private final long hashCode = ThreadLocalRandom.current().nextLong();
protected SocketChannel channel;
private NioHandler eventHandler;
public NioChannelImpl(NioSelectorLoop selectorLoop, NioProcessor processor, SocketChannel channel, NioHandler eventHandler, NioConfig config) {
this.channel = channel;
this.selectorLoop = selectorLoop;
this.processor = processor;
this.eventHandler = eventHandler;
this.id = CONN_ID.incrementAndGet();
this.idleInfo = new IdleInfo();
this.config = config;
closeFuture.setChannel(this);
}
public SelectableChannel javaChannel() {
return channel;
}
public SocketChannel socketChannel() {
return channel;
}
public NioHandler eventHandler() {
return eventHandler;
}
public long getId() {
return id;
}
@Override
public Futures.WriteFuture writeAndFlush(Object msg) {
return processor.writeAndFlush(this, msg);
}
public void setLastReadTime(long lastReadTime) {
idleInfo.setLastReadTime(lastReadTime);
}
public void setLastWriteTime(long lastWriteTime) {
idleInfo.setLastWriteTime(lastWriteTime);
}
public Selector selector() {
return selectorLoop.selector();
}
public Futures.CloseFuture close() {
try {
javaChannel().close();
closeFuture.setSuccess(true);
} catch (final IOException e) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("caught connection exception", e);
}
closeFuture.setSuccess(false);
closeFuture.setCause(e);
eventHandler().exceptionCaught(this, e);
}
closeFuture.notifyListeners();
return closeFuture;
}
@Override
public Futures.CloseFuture getCloseFuture() {
return closeFuture;
}
public boolean isOpen() {
return javaChannel().isOpen();
}
@Override
public boolean isClosed() {
return !isOpen();
}
@Override
public SocketAddress remoteAddress() {
return socketChannel().socket().getRemoteSocketAddress();
}
@Override
public SocketAddress localAddress() {
return socketChannel().socket().getLocalSocketAddress();
}
@Override
public boolean isConnected() {
return !closeFuture.isDone();
}
public IdleInfo getIdleInfo() {
return idleInfo;
}
public NioConfig getConfig() {
return config;
}
public void fireChannelIdle(IdleState state, long currentTime) {
switch (state) {
case BOTH_IDLE:
idleInfo.setLastBothIdleTime(currentTime);
break;
case WRITER_IDLE:
idleInfo.setLastWriteIdleTime(currentTime);
break;
case READER_IDLE:
idleInfo.setLastReadIdleTime(currentTime);
break;
}
eventHandler().channelIdle(this, state);
}
public Decoder getDecoder() {
return decoder;
}
public void setDecoder(Decoder decoder) {
this.decoder = decoder;
}
public Encoder getEncoder() {
return encoder;
}
public void setEncoder(Encoder encoder) {
this.encoder = encoder;
}
@Override
public final int hashCode() {
return (int) hashCode;
}
@Override
public final boolean equals(Object o) {
return this == o;
}
}