Java tutorial
/* * Copyright (c) 2014. Lorem ipsum dolor sit amet, consectetur adipiscing elit. * http://www.apache.org/licenses/LICENSE-2.0 */ package net.NettyEngine4; import com.dc.gameserver.baseConfig.Config; import com.dc.gameserver.extComponents.Kit.ThreadUtils.PriorityThreadFactory; import io.netty.bootstrap.ServerBootstrap; import io.netty.buffer.PooledByteBufAllocator; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelOption; import io.netty.channel.epoll.EpollEventLoopGroup; import io.netty.channel.epoll.EpollServerSocketChannel; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import java.net.InetSocketAddress; /** * @author <br/> * Date: 13-3-11<br/> * Time: ?4:08<br/> * connectMethod:13638363871@163.com<br/> */ @Service public class ServerServiceImpl implements IServer { private static final Logger LOGGER = LoggerFactory.getLogger(ServerServiceImpl.class); /** * ?server,?? * @return boolean */ @Override public boolean IntiServer() { boolean status = true; try { Config.IntiConfig(); return status; } catch (Exception e) { status = false; LOGGER.error("??", e); return status; } } /** * run netty server * NioEventLoopGroup used for NIO Selector based Channels * two NioEventLoopGroup(AioEventLoopGroup) will be used. The first is * used to handle the accept of new connections and the second will serve the IO of them. * IoEventLoopGroupThread +1; * DefaultEventExecutorGroup ? * * bossExecutor:?SocketChannel * workerExecutorSocketChannel?channel/ * executionLogicHandlerThread???? * AIO ?channelgroup?group? * option() is for the NioServerSocketChannel that accepts incoming connections * childOption() is for the Channels accepted by the parent ServerChannel, * which is NioServerSocketChannel in this case. * * ServerBootstrap ?? parent channel * parent channel ? connections * ? connection ? child channel ?? */ @Override public void run() throws Exception { NioEventLoopGroup EventLoopGroupLister = new NioEventLoopGroup(0x1, new PriorityThreadFactory("@+main_reactor+@", Thread.NORM_PRIORITY)); NioEventLoopGroup IOEventLoopGroup = new NioEventLoopGroup(Runtime.getRuntime().availableProcessors() + 1, new PriorityThreadFactory("@+sub_reactor+@", Thread.NORM_PRIORITY)); ServerBootstrap serverBootstrap = new ServerBootstrap(); try { serverBootstrap.group(EventLoopGroupLister, IOEventLoopGroup).channel(NioServerSocketChannel.class) .childOption(ChannelOption.TCP_NODELAY, true).childOption(ChannelOption.SO_KEEPALIVE, true) .childOption(ChannelOption.SO_REUSEADDR, true) //?? .childOption(ChannelOption.ALLOCATOR, new PooledByteBufAllocator(false))// heap buf 's better .childOption(ChannelOption.SO_RCVBUF, 1048576).childOption(ChannelOption.SO_SNDBUF, 1048576) .childHandler(new ServerChannelInitializer());//used to serve the request for the {@link Channel}'s // Bind and start to accept incoming connections. ChannelFuture channelFuture = serverBootstrap .bind(new InetSocketAddress(Config.DEFAULT_VALUE.SERVER_VALUE.gameserverPort)).sync(); if (LOGGER.isDebugEnabled()) LOGGER.debug("server??:" + Config.DEFAULT_VALUE.SERVER_VALUE.gameserverPort); // Wait until the server socket is closed. // In this server, this does not happen, but you can do that to gracefully // shut down your server. channelFuture.channel().closeFuture().sync(); } finally { // Shut down all event loops to terminate all threads. EventLoopGroupLister.shutdownGracefully(); IOEventLoopGroup.shutdownGracefully(); } } /** * jni native Epoll #NioEventLoopGroup EpollEventLoopGroup ---- EventLoopGroup ? #NioEventLoop EpollEventLoop #NioServerSocketChannel EpollServerSocketChannel #NioSocketChannel EpollSocketChannel ---- SocketChannel? ## RHEL/CentOS/Fedora: #sudo yum install autoconf automake libtool glibc-devel.i686 glibc-devel libgcc.i686 make ## Debian/Ubuntu: #sudo apt-get install autoconf automake libtool make gcc-multilib * @throws Exception */ @Override public void runNativeEpoll() throws Exception { EpollEventLoopGroup BossEventLoopGroup = new EpollEventLoopGroup(0x1, new PriorityThreadFactory("@+?", Thread.NORM_PRIORITY)); //mainReactor 1 EpollEventLoopGroup WorkerEventLoopGroup = new EpollEventLoopGroup( Runtime.getRuntime().availableProcessors() + 0x1, new PriorityThreadFactory("@+I/O", Thread.NORM_PRIORITY)); //subReactor ?cpu+1 ServerBootstrap serverBootstrap = new ServerBootstrap(); try { serverBootstrap.group(BossEventLoopGroup, WorkerEventLoopGroup).channel(EpollServerSocketChannel.class) .childOption(ChannelOption.TCP_NODELAY, true).childOption(ChannelOption.SO_KEEPALIVE, true) .childOption(ChannelOption.SO_REUSEADDR, true) //?? .childOption(ChannelOption.ALLOCATOR, new PooledByteBufAllocator(false))// heap buf 's better .childOption(ChannelOption.SO_RCVBUF, 1048576).childOption(ChannelOption.SO_SNDBUF, 1048576) .childHandler(new ServerChannelInitializer());//used to serve the request for the {@link Channel}'s // Bind and start to accept incoming connections. ChannelFuture channelFuture = serverBootstrap .bind(new InetSocketAddress(Config.DEFAULT_VALUE.SERVER_VALUE.gameserverPort)).sync(); if (LOGGER.isDebugEnabled()) LOGGER.debug("server??:" + Config.DEFAULT_VALUE.SERVER_VALUE.gameserverPort); // Wait until the server socket is closed. // In this server, this does not happen, but you can do that to gracefully // shut down your server. channelFuture.channel().closeFuture().sync(); } finally { // Shut down all event loops to terminate all threads. BossEventLoopGroup.shutdownGracefully(); WorkerEventLoopGroup.shutdownGracefully(); } } }