package code.google.nfs.rpc.mina.client;
/**
* nfs-rpc
* Apache License
*
* http://code.google.com/p/nfs-rpc (c) 2011
*/
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.common.ConnectFuture;
import org.apache.mina.common.IoSession;
import org.apache.mina.common.ThreadModel;
import org.apache.mina.transport.socket.nio.SocketConnector;
import org.apache.mina.transport.socket.nio.SocketConnectorConfig;
import code.google.nfs.rpc.NamedThreadFactory;
import code.google.nfs.rpc.client.AbstractClientFactory;
import code.google.nfs.rpc.client.Client;
import code.google.nfs.rpc.mina.serialize.MinaProtocolCodecFilter;
/**
* Mina Client Factory
*
* @author <a href="mailto:bluedavy@gmail.com">bluedavy</a>
*/
public class MinaClientFactory extends AbstractClientFactory {
private static Log LOGGER = LogFactory.getLog(MinaClientFactory.class);
private static final boolean isDebugEnabled = LOGGER.isDebugEnabled();
private static final int processorCount = Runtime.getRuntime().availableProcessors() + 1;
private static final String CONNECTOR_THREADNAME = "MINACLIENT";
private static final ThreadFactory CONNECTOR_TFACTORY = new NamedThreadFactory(CONNECTOR_THREADNAME);
private static final AbstractClientFactory _self = new MinaClientFactory();
private SocketConnector ioConnector;
private MinaClientFactory() {
// only one ioConnector,avoid create too many io processor thread
ioConnector = new SocketConnector(processorCount,
Executors.newCachedThreadPool(CONNECTOR_TFACTORY));
}
public static AbstractClientFactory getInstance() {
return _self;
}
protected Client createClient(String targetIP, int targetPort,
int connectTimeout, String key) throws Exception {
if (isDebugEnabled) {
LOGGER.debug("create connection to :" + targetIP + ":" + targetPort
+ ",timeout is:" + connectTimeout + ",key is:" + key);
}
SocketConnectorConfig cfg = new SocketConnectorConfig();
cfg.setThreadModel(ThreadModel.MANUAL);
if (connectTimeout > 1000) {
cfg.setConnectTimeout((int) connectTimeout / 1000);
} else {
cfg.setConnectTimeout(1);
}
cfg.getSessionConfig().setTcpNoDelay(Boolean.parseBoolean(System.getProperty("nfs.rpc.tcp.nodelay", "true")));
cfg.getFilterChain().addLast("objectserialize",new MinaProtocolCodecFilter());
SocketAddress targetAddress = new InetSocketAddress(targetIP,targetPort);
MinaClientProcessor processor = new MinaClientProcessor(this, key);
ConnectFuture connectFuture = ioConnector.connect(targetAddress, null,processor, cfg);
// wait for connection established
connectFuture.join();
IoSession ioSession = connectFuture.getSession();
if ((ioSession == null) || (!ioSession.isConnected())) {
String targetUrl = targetIP + ":" + targetPort;
LOGGER.error("create connection error,targetaddress is " + targetUrl);
throw new Exception("create connection error,targetaddress is " + targetUrl);
}
if (isDebugEnabled) {
LOGGER.debug("create connection to :" + targetIP + ":" + targetPort
+ ",timeout is:" + connectTimeout + ",key is:" + key
+ " successed");
}
MinaClient client = new MinaClient(ioSession, key, connectTimeout);
processor.setClient(client);
return client;
}
}