com.baidu.jprotobuf.pbrpc.transport.RpcServer.java Source code

Java tutorial

Introduction

Here is the source code for com.baidu.jprotobuf.pbrpc.transport.RpcServer.java

Source

/*
 * Copyright 2002-2014 the original author or authors.
 *
 * 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 com.baidu.jprotobuf.pbrpc.transport;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.ServerChannel;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

import java.net.InetSocketAddress;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.baidu.jprotobuf.pbrpc.management.HttpServer;
import com.baidu.jprotobuf.pbrpc.server.IDLServiceExporter;
import com.baidu.jprotobuf.pbrpc.server.RpcServiceRegistry;

/**
 * RPC server provider by Netty server.
 * 
 * @author xiemalin
 * @since 1.0
 */
public class RpcServer extends ServerBootstrap {

    /**
     * 
     */
    private static final int DEFAULT_WAIT_STOP_INTERVAL = 200;

    private static final Logger LOG = Logger.getLogger(RpcServer.class.getName());

    private AtomicBoolean stop = new AtomicBoolean(false);

    private RpcServerOptions rpcServerOptions;

    private RpcServerPipelineInitializer rpcServerPipelineInitializer;

    private EventLoopGroup bossGroup;
    private EventLoopGroup workerGroup;
    private Channel channel;

    private InetSocketAddress inetSocketAddress;

    private long startTime;

    private HttpServer httpServer;

    /**
     * get the inetSocketAddress
     * @return the inetSocketAddress
     */
    public InetSocketAddress getInetSocketAddress() {
        return inetSocketAddress;
    }

    /**
     * rpcServiceRegistry
     */
    private RpcServiceRegistry rpcServiceRegistry;

    public RpcServer(Class<? extends ServerChannel> serverChannelClass, RpcServerOptions serverOptions,
            RpcServiceRegistry rpcServiceRegistry) {
        if (rpcServiceRegistry == null) {
            throw new RuntimeException("protperty 'rpcServiceRegistry ' is null.");
        }

        if (serverOptions == null) {
            serverOptions = new RpcServerOptions();
        }

        this.bossGroup = new NioEventLoopGroup(serverOptions.getAcceptorThreads());
        this.workerGroup = new NioEventLoopGroup(serverOptions.getWorkThreads());
        this.group(this.bossGroup, this.workerGroup);
        this.channel(serverChannelClass);

        this.option(ChannelOption.SO_BACKLOG, serverOptions.getBacklog());

        this.childOption(ChannelOption.SO_KEEPALIVE, serverOptions.isKeepAlive());
        this.childOption(ChannelOption.SO_REUSEADDR, true);
        this.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
        this.childOption(ChannelOption.TCP_NODELAY, serverOptions.isTcpNoDelay());
        this.childOption(ChannelOption.SO_LINGER, serverOptions.getSoLinger());
        this.childOption(ChannelOption.CONNECT_TIMEOUT_MILLIS, serverOptions.getConnectTimeout());
        this.childOption(ChannelOption.SO_RCVBUF, serverOptions.getReceiveBufferSize());
        this.childOption(ChannelOption.SO_SNDBUF, serverOptions.getSendBufferSize());

        this.rpcServiceRegistry = rpcServiceRegistry;
        // do register meta service
        rpcServiceRegistry.doRegisterMetaService();
        this.rpcServerOptions = serverOptions;
        this.rpcServerPipelineInitializer = new RpcServerPipelineInitializer(rpcServiceRegistry, rpcServerOptions);
        this.childHandler(rpcServerPipelineInitializer);
    }

    public RpcServer(RpcServerOptions serverOptions) {
        this(NioServerSocketChannel.class, serverOptions, new RpcServiceRegistry());
    }

    public RpcServer(RpcServerOptions serverOptions, RpcServiceRegistry rpcServiceRegistry) {
        this(NioServerSocketChannel.class, serverOptions, rpcServiceRegistry);
    }

    public RpcServer() {
        this(new RpcServerOptions());
    }

    public RpcServer(Class<? extends ServerChannel> serverChannelClass) {
        this(serverChannelClass, new RpcServerOptions(), new RpcServiceRegistry());
    }

    public void registerService(IDLServiceExporter service) {
        rpcServiceRegistry.registerService(service);
    }

    public void registerService(final Object target) {
        rpcServiceRegistry.registerService(target);
    }

    public void start(int port) {
        InetSocketAddress inetSocketAddress = new InetSocketAddress(port);
        start(inetSocketAddress);
    }

    public void start(InetSocketAddress sa) {
        LOG.log(Level.INFO, "RPC starting at: " + sa);
        this.bind(sa).addListener(new ChannelFutureListener() {

            public void operationComplete(ChannelFuture future) throws Exception {
                if (future.isSuccess()) {
                    channel = future.channel();
                    // TODO notifyStarted();
                } else {
                    // TODO notifyFailed(future.cause());
                }
            }
        });
        this.inetSocketAddress = sa;

        startTime = System.currentTimeMillis();

        // check if need start http server
        if (rpcServerOptions.getHttpServerPort() > 0) {
            httpServer = new HttpServer(this);
            httpServer.start(rpcServerOptions.getHttpServerPort());
        }
    }

    public void waitForStop() throws InterruptedException {
        while (!stop.get()) {
            Thread.sleep(DEFAULT_WAIT_STOP_INTERVAL);
        }
        shutdown();
    }

    public void stop() {
        stop.set(true);
    }

    public AtomicBoolean getStop() {
        return stop;
    }

    public boolean isStop() {
        return stop.get();
    }

    public void shutdown() {
        stop();
        if (channel != null && channel.isOpen()) {
            channel.close();
        }

        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();

        if (httpServer != null) {
            httpServer.shutdownNow();
        }

    }

    public void setStop(AtomicBoolean stop) {
        this.stop = stop;
    }

    /**
     * get the rpcServerOptions
     * 
     * @return the rpcServerOptions
     */
    public RpcServerOptions getRpcServerOptions() {
        return rpcServerOptions;
    }

    /**
     * set rpcServerOptions value to rpcServerOptions
     * 
     * @param rpcServerOptions the rpcServerOptions to set
     */
    public void setRpcServerOptions(RpcServerOptions rpcServerOptions) {
        this.rpcServerOptions = rpcServerOptions;
    }

    /**
     * get the startTime
     * @return the startTime
     */
    public long getStartTime() {
        return startTime;
    }
}