/* * Copyright (c) 2011-2013 The original author or authors * ------------------------------------------------------ * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Apache License v2.0 which accompanies this distribution. * * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html * * The Apache License v2.0 is available at * http://www.opensource.org/licenses/apache2.0.php * * You may elect to redistribute this code under either of these licenses. */ package io.vertx.core.net.impl; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.channel.Channel; import io.netty.channel.ChannelPipeline; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.stream.ChunkedWriteHandler; import io.netty.handler.timeout.IdleStateHandler; import io.vertx.core.AsyncResult; import io.vertx.core.Handler; import io.vertx.core.buffer.Buffer; import io.vertx.core.impl.ContextImpl; import io.vertx.core.impl.VertxInternal; import io.vertx.core.net.NetClient; import io.vertx.core.net.NetClientOptions; import io.vertx.core.net.NetSocket; import io.vertx.core.spi.metrics.MetricsProvider; import io.vertx.core.spi.metrics.TCPMetrics; import static io.vertx.core.net.impl.VertxHandler.safeBuffer; /** * * This class is thread-safe * * @author <a href="http://tfox.org">Tim Fox</a> */ public class NetClientImpl extends NetClientBase<NetSocketImpl> implements NetClient, MetricsProvider { private final int idleTimeout; private final boolean logEnabled; public NetClientImpl(VertxInternal vertx, NetClientOptions options) { this(vertx, options, true); } public NetClientImpl(VertxInternal vertx, NetClientOptions options, boolean useCreatingContext) { super(vertx, options, useCreatingContext); logEnabled = options.getLogActivity(); idleTimeout = options.getIdleTimeout(); } public synchronized NetClient connect(int port, String host, Handler<AsyncResult<NetSocket>> connectHandler) { connect(port, host, null, connectHandler); return this; } @Override public NetClient connect(int port, String host, String serverName, Handler<AsyncResult<NetSocket>> connectHandler) { doConnect(port, host, serverName, connectHandler != null ? ar -> connectHandler.handle(ar.map(s -> (NetSocket) s)) : null); return this; } @Override protected Object safeObject(Object msg, ByteBufAllocator allocator) { if (msg instanceof ByteBuf) { return safeBuffer((ByteBuf) msg, allocator); } return msg; } @Override protected void initChannel(ChannelPipeline pipeline) { if (logEnabled) { pipeline.addLast("logging", new LoggingHandler()); } if (sslHelper.isSSL()) { // only add ChunkedWriteHandler when SSL is enabled otherwise it is not needed as FileRegion is used. pipeline.addLast("chunkedWriter", new ChunkedWriteHandler()); // For large file / sendfile support } if (idleTimeout > 0) { pipeline.addLast("idle", new IdleStateHandler(0, 0, idleTimeout)); } } @Override protected NetSocketImpl createConnection(VertxInternal vertx, Channel channel, String host, int port, ContextImpl context, SSLHelper helper, TCPMetrics metrics) { return new NetSocketImpl(vertx, channel, host, port, context, helper, metrics); } @Override protected void handleMsgReceived(NetSocketImpl conn, Object msg) { ByteBuf buf = (ByteBuf) msg; conn.handleDataReceived(Buffer.buffer(buf)); } @Override protected void finalize() throws Throwable { // Make sure this gets cleaned up if there are no more references to it // so as not to leave connections and resources dangling until the system is shutdown // which could make the JVM run out of file handles. close(); super.finalize(); } }