com.alibaba.rocketmq.research.rpc.DefaultRPCServer Maven / Gradle / Ivy
/**
* $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;
}
}