Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 package org.ros.internal.transport.tcp;
00018
00019 import com.google.common.base.Preconditions;
00020 import com.google.common.collect.Lists;
00021
00022 import org.apache.commons.logging.Log;
00023 import org.apache.commons.logging.LogFactory;
00024 import org.jboss.netty.bootstrap.ClientBootstrap;
00025 import org.jboss.netty.buffer.ChannelBuffer;
00026 import org.jboss.netty.buffer.ChannelBufferFactory;
00027 import org.jboss.netty.buffer.HeapChannelBufferFactory;
00028 import org.jboss.netty.channel.Channel;
00029 import org.jboss.netty.channel.ChannelFactory;
00030 import org.jboss.netty.channel.ChannelFuture;
00031 import org.jboss.netty.channel.ChannelPipeline;
00032 import org.jboss.netty.channel.group.ChannelGroup;
00033 import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
00034 import org.ros.exception.RosRuntimeException;
00035
00036 import java.net.SocketAddress;
00037 import java.nio.ByteOrder;
00038 import java.util.List;
00039 import java.util.concurrent.Executor;
00040 import java.util.concurrent.TimeUnit;
00041
00045 public class TcpClient {
00046
00047 private static final boolean DEBUG = false;
00048 private static final Log log = LogFactory.getLog(TcpClient.class);
00049
00050 private static final int DEFAULT_CONNECTION_TIMEOUT_DURATION = 5;
00051 private static final TimeUnit DEFAULT_CONNECTION_TIMEOUT_UNIT = TimeUnit.SECONDS;
00052 private static final boolean DEFAULT_KEEP_ALIVE = true;
00053
00054 private final ChannelGroup channelGroup;
00055 private final ChannelFactory channelFactory;
00056 private final ChannelBufferFactory channelBufferFactory;
00057 private final ClientBootstrap bootstrap;
00058 private final List<NamedChannelHandler> namedChannelHandlers;
00059
00060 private Channel channel;
00061
00062 public TcpClient(ChannelGroup channelGroup, Executor executor) {
00063 this.channelGroup = channelGroup;
00064 channelFactory = new NioClientSocketChannelFactory(executor, executor);
00065 channelBufferFactory = new HeapChannelBufferFactory(ByteOrder.LITTLE_ENDIAN);
00066 bootstrap = new ClientBootstrap(channelFactory);
00067 bootstrap.setOption("bufferFactory", channelBufferFactory);
00068 setConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT_DURATION, DEFAULT_CONNECTION_TIMEOUT_UNIT);
00069 setKeepAlive(DEFAULT_KEEP_ALIVE);
00070 namedChannelHandlers = Lists.newArrayList();
00071 }
00072
00073 public void setConnectionTimeout(long duration, TimeUnit unit) {
00074 bootstrap.setOption("connectionTimeoutMillis", TimeUnit.MILLISECONDS.convert(duration, unit));
00075 }
00076
00077 public void setKeepAlive(boolean value) {
00078 bootstrap.setOption("keepAlive", value);
00079 }
00080
00081 public void addNamedChannelHandler(NamedChannelHandler namedChannelHandler) {
00082 namedChannelHandlers.add(namedChannelHandler);
00083 }
00084
00085 public void addAllNamedChannelHandlers(List<NamedChannelHandler> namedChannelHandlers) {
00086 this.namedChannelHandlers.addAll(namedChannelHandlers);
00087 }
00088
00089 public Channel connect(String connectionName, SocketAddress socketAddress) {
00090 TcpClientPipelineFactory tcpClientPipelineFactory = new TcpClientPipelineFactory(channelGroup) {
00091 @Override
00092 public ChannelPipeline getPipeline() {
00093 ChannelPipeline pipeline = super.getPipeline();
00094 for (NamedChannelHandler namedChannelHandler : namedChannelHandlers) {
00095 pipeline.addLast(namedChannelHandler.getName(), namedChannelHandler);
00096 }
00097 return pipeline;
00098 }
00099 };
00100 bootstrap.setPipelineFactory(tcpClientPipelineFactory);
00101 ChannelFuture future = bootstrap.connect(socketAddress).awaitUninterruptibly();
00102 if (future.isSuccess()) {
00103 channel = future.getChannel();
00104 if (DEBUG) {
00105 log.info("Connected to: " + socketAddress);
00106 }
00107 } else {
00108
00109 throw new RosRuntimeException("Connection exception: " + socketAddress, future.getCause());
00110 }
00111 return channel;
00112 }
00113
00114 public ChannelFuture write(ChannelBuffer buffer) {
00115 Preconditions.checkNotNull(channel);
00116 Preconditions.checkNotNull(buffer);
00117 return channel.write(buffer);
00118 }
00119 }