package com.snowcattle.game.service.net;
import com.snowcattle.game.common.ThreadNameFactory;
import com.snowcattle.game.common.constant.Loggers;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import org.slf4j.Logger;
/**
* Created by jiangwenping on 17/2/7.
*/
public abstract class AbstractNettyTcpServerService extends AbstractNettyServerService {
private Logger logger = Loggers.serverLogger;
private EventLoopGroup bossGroup;
private EventLoopGroup workerGroup;
private ThreadNameFactory bossThreadNameFactory;
private ThreadNameFactory workerThreadNameFactory;
private ChannelInitializer channelInitializer;
private ChannelFuture serverChannelFuture;
public AbstractNettyTcpServerService(String serviceId, int serverPort, String bossTreadName, String workThreadName,ChannelInitializer channelInitializer) {
super(serviceId, serverPort);
this.bossThreadNameFactory = new ThreadNameFactory(bossTreadName);
this.workerThreadNameFactory = new ThreadNameFactory(workThreadName);
this.channelInitializer = channelInitializer;
}
@Override
public boolean startService() throws Exception{
boolean serviceFlag = super.startService();
bossGroup = new NioEventLoopGroup(1, bossThreadNameFactory);
workerGroup = new NioEventLoopGroup(0, workerThreadNameFactory);
try{
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap = serverBootstrap.group(bossGroup, workerGroup);
serverBootstrap.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024)
.childOption(ChannelOption.SO_REUSEADDR, true) //重用地址
.childOption(ChannelOption.SO_RCVBUF, 65536)
.childOption(ChannelOption.SO_SNDBUF, 65536)
.childOption(ChannelOption.TCP_NODELAY, true)
.childOption(ChannelOption.SO_KEEPALIVE, true)
.childOption(ChannelOption.ALLOCATOR, new PooledByteBufAllocator(false)) // heap buf 's better
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(channelInitializer);
serverChannelFuture = serverBootstrap.bind(serverPort).sync();
//TODO这里会阻塞main线程,暂时先注释掉
// serverChannelFuture.channel().closeFuture().sync();
serverChannelFuture.channel().closeFuture().addListener(ChannelFutureListener.CLOSE);
}catch (Exception e) {
logger.error(e.toString(), e);
serviceFlag = false;
}
return serviceFlag;
}
@Override
public boolean stopService() throws Exception{
boolean flag = super.stopService();
if(bossGroup != null){
bossGroup.shutdownGracefully();
}
if(workerGroup != null){
workerGroup.shutdownGracefully();
}
return flag;
}
public void finish() throws InterruptedException {
// serverChannelFuture.channel().closeFuture().sync();
}
}