package code.google.nfs.rpc.netty.client; /** * nfs-rpc * Apache License * * http://code.google.com/p/nfs-rpc (c) 2011 */ import java.net.InetSocketAddress; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFutureListener; import code.google.nfs.rpc.RequestWrapper; import code.google.nfs.rpc.ResponseWrapper; import code.google.nfs.rpc.client.AbstractClient; import code.google.nfs.rpc.client.Client; import code.google.nfs.rpc.client.ClientFactory; /** * Netty Client * * @author <a href="mailto:bluedavy@gmail.com">bluedavy</a> */ public class NettyClient extends AbstractClient { private static final Log LOGGER = LogFactory.getLog(NettyClient.class); private ChannelFuture cf; private String key; private int connectTimeout; public NettyClient(ChannelFuture cf, String key, int connectTimeout) { this.cf = cf; this.key = key; this.connectTimeout = connectTimeout; } public void sendRequest(final RequestWrapper wrapper, final int timeout) throws Exception { final long beginTime = System.currentTimeMillis(); final Client self = this; ChannelFuture writeFuture = cf.getChannel().write(wrapper); // use listener to avoid wait for write & thread context switch writeFuture.addListener(new ChannelFutureListener() { public void operationComplete(ChannelFuture future) throws Exception { if (future.isSuccess()) { return; } String errorMsg = ""; // write timeout if (System.currentTimeMillis() - beginTime >= timeout) { errorMsg = "write to send buffer consume too long time(" + (System.currentTimeMillis() - beginTime) + "),request id is:" + wrapper.getId(); } if (future.isCancelled()) { errorMsg = "Send request to " + cf.getChannel().toString() + " cancelled by user,request id is:" + wrapper.getId(); } if (!future.isSuccess()) { if (cf.getChannel().isConnected()) { // maybe some exception,so close the channel cf.getChannel().close(); } else { NettyClientFactory.getInstance().removeClient(key, self); } errorMsg = "Send request to " + cf.getChannel().toString() + " error" + future.getCause(); } LOGGER.error(errorMsg); ResponseWrapper response = new ResponseWrapper(wrapper.getId(), wrapper.getCodecType(), wrapper.getProtocolType()); response.setException(new Exception(errorMsg)); self.putResponse(response); } }); } public String getServerIP() { return ((InetSocketAddress) cf.getChannel().getRemoteAddress()) .getHostName(); } public int getServerPort() { return ((InetSocketAddress) cf.getChannel().getRemoteAddress()) .getPort(); } public int getConnectTimeout() { return connectTimeout; } public long getSendingBytesSize() { // TODO: implement it return 0; } public ClientFactory getClientFactory() { return NettyClientFactory.getInstance(); } }