nikoladasm.aspark.server.ASparkServer.java Source code

Java tutorial

Introduction

Here is the source code for nikoladasm.aspark.server.ASparkServer.java

Source

/*
 *  ASpark
 *  Copyright (C) 2015  Nikolay Platov
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package nikoladasm.aspark.server;

import java.net.InetSocketAddress;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLContext;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import nikoladasm.aspark.ExceptionMap;
import nikoladasm.aspark.WebSocketMap;
import nikoladasm.aspark.dispatcher.Dispatcher;

public class ASparkServer {

    private static final InternalLogger LOG = InternalLoggerFactory
            .getInstance(nikoladasm.aspark.server.ASparkServer.class);

    private static final int DEFAULT_MAX_CONTENT_LENGTH = 20480;
    private String ipAddress;
    private int port;
    private Dispatcher dispatcher;
    private ExceptionMap exceptionMap;
    private WebSocketMap webSockets;
    private int maxContentLength;
    private SSLContext sslContext;
    private CountDownLatch latch;
    private String serverName;

    private volatile Channel channel;
    private volatile EventLoopGroup bossGroup;
    private volatile EventLoopGroup workerGroup;
    private volatile boolean started;

    private Executor pool;

    public ASparkServer(CountDownLatch latch, Executor pool, String ipAddress, int port, Dispatcher dispatcher,
            ExceptionMap exceptionMap, WebSocketMap webSockets, SSLContext sslContext, int maxContentLength,
            String serverName) {
        this.pool = pool;
        this.latch = latch;
        this.ipAddress = ipAddress;
        this.port = port;
        this.dispatcher = dispatcher;
        this.exceptionMap = exceptionMap;
        this.webSockets = webSockets;
        this.sslContext = sslContext;
        this.maxContentLength = maxContentLength;
        this.serverName = serverName;
    }

    public ASparkServer(CountDownLatch latch, Executor pool, String ipAddress, int port, Dispatcher dispatcher,
            ExceptionMap exceptionMap, WebSocketMap webSockets, SSLContext sslContext, String serverName) {
        this(latch, pool, ipAddress, port, dispatcher, exceptionMap, webSockets, sslContext,
                DEFAULT_MAX_CONTENT_LENGTH, serverName);
    }

    public ASparkServer(CountDownLatch latch, Executor pool, String ipAddress, int port, Dispatcher dispatcher,
            ExceptionMap exceptionMap, WebSocketMap webSockets, int maxContentLength, String serverName,
            Properties mimeTypes) {
        this(latch, pool, ipAddress, port, dispatcher, exceptionMap, webSockets, null, maxContentLength,
                serverName);
    }

    public ASparkServer(CountDownLatch latch, Executor pool, String ipAddress, int port, Dispatcher dispatcher,
            ExceptionMap exceptionMap, WebSocketMap webSockets, String serverName) {
        this(latch, pool, ipAddress, port, dispatcher, exceptionMap, webSockets, null, DEFAULT_MAX_CONTENT_LENGTH,
                serverName);
    }

    public void start() {
        bossGroup = new NioEventLoopGroup();
        workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap server = new ServerBootstrap();
            server.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                    .childHandler(new ServerInitializer(sslContext, maxContentLength, ipAddress, port, dispatcher,
                            exceptionMap, webSockets, serverName, pool))
                    .option(ChannelOption.SO_BACKLOG, 1024).option(ChannelOption.SO_KEEPALIVE, true)
                    .option(ChannelOption.TCP_NODELAY, true).childOption(ChannelOption.SO_KEEPALIVE, true)
                    .childOption(ChannelOption.TCP_NODELAY, true);
            channel = server.bind(new InetSocketAddress(ipAddress, port)).sync().channel();
            started = true;
            latch.countDown();
            LOG.info("Netty server started");
        } catch (InterruptedException e) {
            LOG.error("Unexpected exception", e);
            bossGroup.shutdownGracefully(0, 0, TimeUnit.SECONDS);
            workerGroup.shutdownGracefully(0, 0, TimeUnit.SECONDS);
            started = false;
            latch.countDown();
        }
    }

    public boolean isStarted() {
        return started;
    }

    public void stop() {
        if (channel == null)
            return;
        channel.close().syncUninterruptibly();
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
        bossGroup.terminationFuture().syncUninterruptibly();
        workerGroup.terminationFuture().syncUninterruptibly();
        started = false;
        LOG.info("Netty server stopped");
    }

    public void await() {
        if (channel == null)
            return;
        try {
            channel.closeFuture().sync();
        } catch (InterruptedException e) {
            LOG.warn("Unexpected exception", e);
            bossGroup.shutdownGracefully(0, 0, TimeUnit.SECONDS);
            workerGroup.shutdownGracefully(0, 0, TimeUnit.SECONDS);
            started = false;
        }
    }
}