package com.ustcinfo.rpc.netty4;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import java.net.InetSocketAddress;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.ustcinfo.rpc.RequestWrapper;
import com.ustcinfo.rpc.ResponseWrapper;
import com.ustcinfo.rpc.client.AbstractClient;
import com.ustcinfo.rpc.client.ClientFactory;
public class Netty4Client extends AbstractClient {
private static final Log LOGGER = LogFactory.getLog(Netty4Client.class);
private ChannelFuture cf;
private String key;
private int connectTimeout;
public Netty4Client(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();
ChannelFuture writeFuture = cf.channel().writeAndFlush(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.channel().toString()
+ " cancelled by user,request id is:"
+ wrapper.getId();
}
if (!future.isSuccess()) {
if (cf.channel().isActive()) {
// maybe some exception,so close the channel
cf.channel().close();
}
else {
Netty4ClientFactory.getInstance().removeClient(key);
}
errorMsg = "Send request to " + cf.channel().toString()
+ " error" + future.cause();
}
LOGGER.error(errorMsg);
ResponseWrapper response = new ResponseWrapper(wrapper.getId(), wrapper.getCodecType());
response.setException(new Exception(errorMsg));
}
});
}
public String getServerIP() {
return ((InetSocketAddress) cf.channel().remoteAddress())
.getHostName();
}
public int getServerPort() {
return ((InetSocketAddress) cf.channel().remoteAddress())
.getPort();
}
public int getConnectTimeout() {
return connectTimeout;
}
public long getSendingBytesSize() {
return 0;
}
public ClientFactory getClientFactory() {
return Netty4ClientFactory.getInstance();
}
}