Java tutorial
/* * Copyright (C) 2011 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package org.ros.internal.transport.tcp; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import org.apache.commons.logging.Log; import org.jboss.netty.bootstrap.ClientBootstrap; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBufferFactory; import org.jboss.netty.buffer.HeapChannelBufferFactory; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelFactory; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.group.ChannelGroup; import org.jboss.netty.channel.socket.nio.NioClientBossPool; import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory; import org.jboss.netty.channel.socket.nio.NioWorkerPool; import org.jboss.netty.util.HashedWheelTimer; import org.ros.exception.RosRuntimeException; import org.ros.log.RosLogFactory; import java.net.SocketAddress; import java.nio.ByteOrder; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; /** * @author damonkohler@google.com (Damon Kohler) */ public class TcpRosClient { private static final Log log = RosLogFactory.getLog(TcpRosClient.class); private static final int DEFAULT_CONNECTION_TIMEOUT_DURATION = 5; private static final TimeUnit DEFAULT_CONNECTION_TIMEOUT_UNIT = TimeUnit.SECONDS; private static final boolean DEFAULT_KEEP_ALIVE = true; private final ChannelGroup channelGroup; private final ChannelFactory channelFactory; private final ChannelBufferFactory channelBufferFactory; private final ClientBootstrap bootstrap; private final List<NamedChannelHandler> namedChannelHandlers; private Channel channel; private HashedWheelTimer nettyTimer; public TcpRosClient(ChannelGroup channelGroup, HashedWheelTimer nettyTimer, Executor executor) { this.channelGroup = channelGroup; this.nettyTimer = nettyTimer; channelFactory = new NioClientSocketChannelFactory(new NioClientBossPool(executor, 1), new NioWorkerPool(executor, Runtime.getRuntime().availableProcessors() * 2)); channelBufferFactory = new HeapChannelBufferFactory(ByteOrder.LITTLE_ENDIAN); bootstrap = new ClientBootstrap(channelFactory); bootstrap.setOption("bufferFactory", channelBufferFactory); setConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT_DURATION, DEFAULT_CONNECTION_TIMEOUT_UNIT); setKeepAlive(DEFAULT_KEEP_ALIVE); namedChannelHandlers = Lists.newArrayList(); } public void setConnectionTimeout(long duration, TimeUnit unit) { bootstrap.setOption("connectionTimeoutMillis", TimeUnit.MILLISECONDS.convert(duration, unit)); } public void setKeepAlive(boolean value) { bootstrap.setOption("keepAlive", value); } public void addNamedChannelHandler(NamedChannelHandler namedChannelHandler) { namedChannelHandlers.add(namedChannelHandler); } public void addAllNamedChannelHandlers(List<NamedChannelHandler> namedChannelHandlers) { this.namedChannelHandlers.addAll(namedChannelHandlers); } public void connect(String connectionName, SocketAddress socketAddress) { TcpRosClientPipelineFactory tcpClientPipelineFactory = new TcpRosClientPipelineFactory(channelGroup) { @Override public ChannelPipeline getPipeline() { ChannelPipeline pipeline = super.getPipeline(); for (NamedChannelHandler namedChannelHandler : namedChannelHandlers) { pipeline.addLast(namedChannelHandler.getName(), namedChannelHandler); } return pipeline; } }; bootstrap.setPipelineFactory(tcpClientPipelineFactory); ChannelFuture future = bootstrap.connect(socketAddress).awaitUninterruptibly(); if (future.isSuccess()) { channel = future.getChannel(); if (log.isDebugEnabled()) { log.debug("Connected to: " + socketAddress); } } else { // We expect the first connection to succeed. If not, fail fast. throw new RosRuntimeException("Connection exception: " + socketAddress, future.getCause()); } } /** * Get the netty channel for this client. * * @return the netty channel */ public Channel getChannel() { return channel; } /** * Is the client connected to the other side? * * @return {@code true} if connected */ public boolean isConnected() { return channel.isConnected(); } public ChannelFuture write(ChannelBuffer buffer) { Preconditions.checkNotNull(channel); Preconditions.checkNotNull(buffer); return channel.write(buffer); } /** * Shutdown the client. */ public void shutdown() { bootstrap.shutdown(); } }