net.NettyEngine3.core.NServerFrameNettyStart.java Source code

Java tutorial

Introduction

Here is the source code for net.NettyEngine3.core.NServerFrameNettyStart.java

Source

/*
 * Copyright (c) 2014. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

package net.NettyEngine3.core;

import org.jboss.netty.bootstrap.Bootstrap;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelHandler;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.handler.execution.ExecutionHandler;
import org.jboss.netty.handler.execution.MemoryAwareThreadPoolExecutor;
import org.jboss.netty.handler.timeout.IdleStateHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created with IntelliJ IDEA.
 * User: CHENLEI
 * Date: 12-10-30
 * Time: ?11:03
 * To change this template use File | Settings | File Templates.
 * start gameSever Socket
 */
@Service
public final class NServerFrameNettyStart implements INettyServer {
    private static final Logger LOG = LoggerFactory.getLogger(NServerFrameNettyStart.class);
    public static boolean debug;
    private ServerBootstrap bootstrap = null;
    private final String[] optionList = { "tcpNoDelay", "keepAlive", "readWriteFair", "child.tcpNoDelay",
            "child.reuseAddress", "readWriteFair" };
    private ExecutionHandler executionHandler = null;

    public NServerFrameNettyStart() {

    }

    @Override
    public void startServer() {
        try {
            getServerBootstrap();
            configureServerBootStrap(this.bootstrap, optionList);
        } catch (Exception e) {
            LOG.error("netty start failed ", e);
            this.releaseServerResources();
        }

    }

    /**
     * ?server?
     *
     * @return boolean
     */
    @Override
    @PostConstruct
    public boolean IntiServer() {
        //        NServerConfig mServerConfig=new NServerConfig();
        //        return mServerConfig.IntiServerConfig();
        return false;
    }

    /**
     * If thread pools or TCP/IP parameters or the pipeline factory need to be
     * modified then it is this method that needs to be overriden.
     *
     * @param optionsList Used to set tcp ip options like noDelay etc.
     */
    @Override
    public void configureServerBootStrap(ServerBootstrap bootstrap, String[] optionsList) {
        // For clients who do not use spring.
        if (null == bootstrap) {
            getServerBootstrap();
        }
        if (bootstrap != null) {
            bootstrap.setPipelineFactory(getPipelineFactory());
            if (null != optionsList && optionsList.length > 0) {
                for (String option : optionsList) {
                    bootstrap.setOption(option, true);
                }
            }
            bootstrap.setOption("receiveBufferSize", 0x100000 * 0x40);
            bootstrap.setOption("child.receiveBufferSize", 0x100000 * 0x40);
            bootstrap.setOption("tcpNoDelay", 0);//Runtime ClassCastException
            bootstrap.bind(new InetSocketAddress(9999));
        }
    }

    /**
     * createServerBootstrap will create a pipeline factory and save it as a
     * class variable. This method can then be used to retrieve that value.
     *
     * @return Returns the channel pipeline factory that is associated with this
     *         netty server.
     *
     *   ExecutionHandler?????handler
     *   worker?ExecutionHandler??
     *   ChannelFactoryworker
     *   ??
     *   ???
     *   executionHandlerThread will be executed the task of {@link com.dc.gameserver.ExtComponents.NettyEngine3.service.HandleController}  it's runnable
     */
    @Override
    public ChannelPipelineFactory getPipelineFactory() {
        //??bufobjectSession  maxChannelMemorySize maxTotalMemorySize
        //disabled the value of code 0;
        // Deadlock can happen when MemoryAwareThreadPoolExecutor with limit is used
        // fixed by netty 3.6.6.final
        executionHandler = new ExecutionHandler(
                new MemoryAwareThreadPoolExecutor(Runtime.getRuntime().availableProcessors() + 1, 0, 0, 0,
                        TimeUnit.SECONDS, new PriorityThreadFactory("logic_handle", Thread.NORM_PRIORITY + 1)));
        ChannelHandler idleStateHandler = new IdleStateHandler(NServerFrameUtil.timer, 10, 0, 0, TimeUnit.SECONDS);
        return new NServerFrameChannelPipelineFactory(idleStateHandler, executionHandler);
    }

    /**
     * main_reactor and  sub_reactor
     * @return
     */
    @Override
    public Bootstrap getServerBootstrap() {
        ChannelFactory factory = new NioServerSocketChannelFactory(
                Executors.newFixedThreadPool(0x1,
                        new PriorityThreadFactory("@+main_reactor+@", Thread.NORM_PRIORITY)),
                Executors.newCachedThreadPool(
                        new PriorityThreadFactory("@+sub_reactor+@", Thread.NORM_PRIORITY)));
        bootstrap = new ServerBootstrap(factory);
        return bootstrap;
    }

    /**
     * ?
     */
    @Override
    public final void releaseServerResources() {
        this.executionHandler.releaseExternalResources();
        bootstrap.releaseExternalResources();
        NServerFrameUtil.timer.stop();
        NServerFrameUtil.globalTrafficShapingHandler.releaseExternalResources();
    }

    /**
     * 
     */
    private class PriorityThreadFactory implements ThreadFactory {
        private int _prio;
        private String _name;
        private AtomicInteger _threadNumber = new AtomicInteger(1);
        private ThreadGroup _group;

        /**
         *
         * @param name ??
         * @param priority   
         */
        public PriorityThreadFactory(String name, int priority) {
            _prio = priority;
            _name = name;
            _group = new ThreadGroup(_name);
        }

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(_group, r);
            t.setName(_name + "-" + "#-" + _threadNumber.getAndIncrement());
            t.setPriority(_prio);
            return t;
        }

        public ThreadGroup getGroup() {
            return _group;
        }
    }

}