net.NettyEngine4.ServerServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for net.NettyEngine4.ServerServiceImpl.java

Source

/*
 * 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();
        }
    }

}