net.qing.sms.simulator.NettySmsSimulatorServer.java Source code

Java tutorial

Introduction

Here is the source code for net.qing.sms.simulator.NettySmsSimulatorServer.java

Source

/**
 * Copyright 2012 Nikita Koksharov
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.qing.sms.simulator;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.epoll.EpollServerSocketChannel;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;

import java.net.InetSocketAddress;

import net.qing.sms.simulator.cmpp.CMPPDecoder;
import net.qing.sms.simulator.cmpp3.CMPP3Decoder;
import net.qing.sms.simulator.sgip.SGIPDecoder;
import eet.evar.tool.logger.Logger;
import eet.evar.tool.logger.LoggerFactory;

/**
 * Fully thread-safe.
 * 
 */
public class NettySmsSimulatorServer {
    private static final Logger log = LoggerFactory.getLogger(NettySmsSimulatorServer.class);
    private final Configuration configuration;
    private EventLoopGroup bossGroup;
    private EventLoopGroup workerGroup;
    private final long serverStartTime = System.currentTimeMillis();// ??
    private final CancelableScheduler scheduler = new HashedWheelScheduler();

    public NettySmsSimulatorServer(Configuration configuration) {
        this.configuration = configuration;
    }

    /**
     * Get all clients connected to default namespace
     * 
     * @return clients collection
     */

    public long getServerStartTime() {
        return serverStartTime;
    }

    /**
     * Start server
     */
    public void start() throws Exception {
        initGroups();
        Class channelClass = NioServerSocketChannel.class;
        if (configuration.isUseLinuxNativeEpoll()) {
            channelClass = EpollServerSocketChannel.class;
        }
        ServerBootstrap b = new ServerBootstrap();
        if (configuration.getServerType().equals("sgip")) {
            b.group(bossGroup, workerGroup).channel(channelClass).childHandler(new SGIPSimulatorChannelInitializer(
                    serverStartTime, scheduler, configuration.getPingTimeout()));
        } else if (configuration.getServerType().equals("cmpp")) {
            b.group(bossGroup, workerGroup).channel(channelClass).childHandler(new CMPPSimulatorChannelInitializer(
                    serverStartTime, scheduler, configuration.getPingTimeout()));
        } else if (configuration.getServerType().equals("cmpp3")) {
            b.group(bossGroup, workerGroup).channel(channelClass).childHandler(new CMPP3SimulatorChannelInitializer(
                    serverStartTime, scheduler, configuration.getPingTimeout()));
        } else {
            log.error("????" + configuration.getServerType());
            System.exit(-1);
        }
        applyConnectionOptions(b);
        InetSocketAddress addr = new InetSocketAddress(configuration.getPort());
        if (configuration.getHostname() != null) {
            addr = new InetSocketAddress(configuration.getHostname(), configuration.getPort());
        }
        ChannelFuture f = b.bind(addr).sync();
        log.info("sms_simulator??host:" + configuration.getHostname() + ", port:"
                + configuration.getPort());
        f.channel().closeFuture().sync();
    }

    class CMPPSimulatorChannelInitializer extends ChannelInitializer<SocketChannel> {
        private ChannelHandler cmppSimulatorInboundHandler = null;

        public CMPPSimulatorChannelInitializer(long serverStartTime, CancelableScheduler scheduler,
                int pingTimeout) {
            cmppSimulatorInboundHandler = new CMPP2SimulatorHandler(serverStartTime, scheduler,
                    configuration.getPingTimeout());
        }

        @Override
        public void initChannel(SocketChannel ch) throws Exception {
            ch.pipeline().addLast("frameDecoder",
                    new LengthFieldBasedFrameDecoder(1024 * 1024 * 1024, 0, 4, -4, 0));
            ch.pipeline().addLast("userDecoder", new CMPPDecoder());
            ch.pipeline().addLast(cmppSimulatorInboundHandler);
        }
    }

    class CMPP3SimulatorChannelInitializer extends ChannelInitializer<SocketChannel> {
        private ChannelHandler cmpp3SimulatorInboundHandler = null;

        public CMPP3SimulatorChannelInitializer(long serverStartTime, CancelableScheduler scheduler,
                int pingTimeout) {
            cmpp3SimulatorInboundHandler = new CMPP3SimulatorHandler(serverStartTime, scheduler,
                    configuration.getPingTimeout());
        }

        @Override
        public void initChannel(SocketChannel ch) throws Exception {
            ch.pipeline().addLast("frameDecoder",
                    new LengthFieldBasedFrameDecoder(1024 * 1024 * 1024, 0, 4, -4, 0));
            ch.pipeline().addLast("userDecoder", new CMPP3Decoder());
            ch.pipeline().addLast(cmpp3SimulatorInboundHandler);
        }
    }

    class SGIPSimulatorChannelInitializer extends ChannelInitializer<SocketChannel> {
        private ChannelHandler sgipSimulatorInboundHandler = null;

        public SGIPSimulatorChannelInitializer(long serverStartTime, CancelableScheduler scheduler,
                int pingTimeout) {
            sgipSimulatorInboundHandler = new SGIPSimulatorHandler(serverStartTime, scheduler,
                    configuration.getPingTimeout());
        }

        @Override
        public void initChannel(SocketChannel ch) throws Exception {
            ch.pipeline().addLast("frameDecoder",
                    new LengthFieldBasedFrameDecoder(1024 * 1024 * 1024, 0, 4, -4, 0));
            ch.pipeline().addLast("userDecoder", new SGIPDecoder());
            ch.pipeline().addLast(sgipSimulatorInboundHandler);
        }
    }

    protected void applyConnectionOptions(ServerBootstrap bootstrap) {
        SocketConfig config = configuration.getSocketConfig();
        bootstrap.childOption(ChannelOption.TCP_NODELAY, config.isTcpNoDelay());
        if (config.getTcpSendBufferSize() != -1) {
            bootstrap.childOption(ChannelOption.SO_SNDBUF, config.getTcpSendBufferSize());
        }
        if (config.getTcpReceiveBufferSize() != -1) {
            bootstrap.childOption(ChannelOption.SO_RCVBUF, config.getTcpReceiveBufferSize());
        }
        // bootstrap.option(ChannelOption.ALLOCATOR,
        // PooledByteBufAllocator.DEFAULT);
        bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
        // bootstrap.childOption(ChannelOption.ALLOCATOR,
        // PooledByteBufAllocator.DEFAULT);
        bootstrap.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
        bootstrap.childOption(ChannelOption.SO_KEEPALIVE, config.isTcpKeepAlive());
        bootstrap.option(ChannelOption.SO_LINGER, config.getSoLinger());
        bootstrap.option(ChannelOption.SO_REUSEADDR, config.isReuseAddress());
        bootstrap.option(ChannelOption.SO_BACKLOG, config.getAcceptBackLog());
    }

    protected void initGroups() {
        if (configuration.isUseLinuxNativeEpoll()) {
            bossGroup = new EpollEventLoopGroup(configuration.getBossThreads());
            workerGroup = new EpollEventLoopGroup(configuration.getWorkerThreads());
        } else {
            bossGroup = new NioEventLoopGroup(configuration.getBossThreads());
            workerGroup = new NioEventLoopGroup(configuration.getWorkerThreads());
        }
    }

    /**
     * Stop server
     */
    public void stop() {
        bossGroup.shutdownGracefully().syncUninterruptibly();
        workerGroup.shutdownGracefully().syncUninterruptibly();
        scheduler.shutdown();
        log.info("sms_simulator??");
    }

    /**
     * Allows to get configuration provided during server creation. Further
     * changes on this object not affect server.
     * 
     * @return Configuration object
     */
    public Configuration getConfiguration() {
        return configuration;
    }

    /**
     * ?
     * 
     * @return
     */
    public CancelableScheduler getScheduler() {
        return scheduler;
    }
}