All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.rocketmq.research.rpc.DefaultRPCServer Maven / Gradle / Ivy

There is a newer version: 3.1.8
Show newest version
/**
 * $Id: DefaultRPCServer.java 1831 2013-05-16 01:39:51Z shijia.wxr $
 */
package com.alibaba.rocketmq.research.rpc;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import com.alibaba.rocketmq.common.ServiceThread;


/**
 * 服务端实现
 * 
 * @author shijia.wxr
 */
public class DefaultRPCServer implements RPCServer {
    private final int listenPort;
    private ServerSocketChannel serverSocketChannel;
    private Selector selector;
    private SocketAddress socketAddressListen;
    private RPCProcessor rpcServerProcessor;

    private List connectionList = new LinkedList();
    private final AcceptSocketService acceptSocketService = new AcceptSocketService();
    private final ThreadPoolExecutor executor;

    class AcceptSocketService extends ServiceThread {

        @Override
        public void run() {
            System.out.println(this.getServiceName() + " service started");

            while (!this.isStoped()) {
                try {
                    DefaultRPCServer.this.selector.select(1000);
                    Set selected = DefaultRPCServer.this.selector.selectedKeys();
                    ArrayList selectedList = new ArrayList(selected);
                    Collections.shuffle(selectedList);
                    for (SelectionKey k : selectedList) {
                        if ((k.readyOps() & SelectionKey.OP_ACCEPT) != 0) {
                            SocketChannel sc = ((ServerSocketChannel) k.channel()).accept();
                            System.out.println("receive new connection, "
                                    + sc.socket().getRemoteSocketAddress());
                            Connection newConnection =
                                    new Connection(sc, DefaultRPCServer.this.rpcServerProcessor,
                                        DefaultRPCServer.this.executor);

                            // if (DefaultRPCServer.this.clientConnection !=
                            // null) {
                            // System.out.println("close old client connection, "
                            // +
                            // DefaultRPCServer.this.clientConnection.getSocketChannel().socket()
                            // .getRemoteSocketAddress());
                            // DefaultRPCServer.this.clientConnection.shutdown();
                            // }

                            DefaultRPCServer.this.connectionList.add(newConnection);
                            newConnection.start();
                        }
                        // TODO, CLOSE SOCKET
                        else {
                            System.out.println("Unexpected ops in select " + k.readyOps());
                        }
                    }

                    selected.clear();
                }
                catch (Exception e) {
                    System.out.println(this.getServiceName() + " service has exception.");
                    System.out.println(e.getMessage());
                }
            }

            System.out.println(this.getServiceName() + " service end");
        }


        @Override
        public String getServiceName() {
            return AcceptSocketService.class.getSimpleName();
        }
    }


    public DefaultRPCServer(final int listenPort, final int minPoolSize, final int maxPoolSize)
            throws IOException {
        this.listenPort = listenPort;
        this.socketAddressListen = new InetSocketAddress(this.listenPort);
        this.serverSocketChannel = ServerSocketChannel.open();
        this.selector = Selector.open();
        this.serverSocketChannel.socket().setReuseAddress(true);
        this.serverSocketChannel.socket().bind(this.socketAddressListen);
        this.serverSocketChannel.configureBlocking(false);
        this.serverSocketChannel.register(this.selector, SelectionKey.OP_ACCEPT);

        this.executor =
                new ThreadPoolExecutor(minPoolSize, maxPoolSize, 60L, TimeUnit.SECONDS,
                    new SynchronousQueue(), new ThreadFactory() {
                        private volatile long threadCnt = 0;


                        @Override
                        public Thread newThread(Runnable r) {
                            return new Thread(r, "RPCHandleThreadPool_" + String.valueOf(this.threadCnt++));
                        }
                    });
    }


    @Override
    public void start() {
        this.acceptSocketService.start();
    }


    @Override
    public void shutdown() {
        this.acceptSocketService.shutdown();

        for (Connection c : this.connectionList) {
            c.shutdown();
        }

        try {
            this.selector.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }

        try {
            this.serverSocketChannel.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }


    @Override
    public void registerProcessor(RPCProcessor processor) {
        this.rpcServerProcessor = processor;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy