package com.sissi.server.netty.impl; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelInitializer; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.sissi.commons.Trace; import com.sissi.server.Server; import com.sissi.server.netty.ServerLoopGroup; import com.sissi.server.status.ServerStatus; /** * @author kim 2013-11-19 */ public class NioServer implements Server { private final Log log = LogFactory.getLog(this.getClass()); private final ServerBootstrap bootstrap = new ServerBootstrap(); private final ChannelInitializer<SocketChannel> channelInitializer; private final ServerLoopGroup serverLoopGroup; private final ServerStatus serverStatus; private final int port; public NioServer(ChannelInitializer<SocketChannel> channelInitializer, ServerLoopGroup serverLoopGroup, ServerStatus serverStatus, int port) { super(); this.channelInitializer = channelInitializer; this.serverLoopGroup = serverLoopGroup; this.serverStatus = serverStatus; this.port = port; } @Override public NioServer start() { try { this.bootstrap.group(this.serverLoopGroup.boss(), this.serverLoopGroup.event()).channel(NioServerSocketChannel.class).childHandler(this.channelInitializer); this.bootstrap.bind(this.port).addListener(new FailShutdownGenericFutureListener()); this.serverStatus.update(ServerStatus.STATUS_STARTED, String.valueOf(System.currentTimeMillis())); } catch (Exception e) { this.log.fatal(e.toString()); Trace.trace(this.log, e); this.closeAll(); } return this; } @Override public NioServer stop() { return this.closeAll(); } private NioServer closeAll() { this.serverLoopGroup.boss().shutdownGracefully(); this.serverLoopGroup.event().shutdownGracefully(); return this; } private class FailShutdownGenericFutureListener implements GenericFutureListener<Future<Void>> { public void operationComplete(Future<Void> future) throws Exception { if (!future.isSuccess()) { NioServer.this.closeAll(); NioServer.this.log.fatal(future.cause()); Trace.trace(NioServer.this.log, future.cause()); } } } }