All Downloads are FREE. Search and download functionalities are using the official Maven repository.

rpc.turbo.transport.client.NettyClientConnector Maven / Gradle / Ivy

There is a newer version: 0.0.9
Show newest version
package rpc.turbo.transport.client;

import java.io.Closeable;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Objects;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.WriteBufferWaterMark;
import io.netty.channel.epoll.EpollChannelOption;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.epoll.EpollSocketChannel;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import rpc.turbo.config.HostPort;
import rpc.turbo.serialization.Serializer;
import rpc.turbo.transport.client.future.RequestWithFuture;
import rpc.turbo.transport.client.handler.TurboChannelInitializer;

final class NettyClientConnector implements Closeable {
	private static final Log logger = LogFactory.getLog(NettyClientConnector.class);

	public final HostPort serverAddress;

	private final Serializer serializer;
	private final EventLoopGroup eventLoopGroup;
	private final int connectCount;

	public volatile HostPort clientAddress;
	private volatile Channel[] channels;

	/**
	 * 
	 * @param eventLoopGroup
	 * @param serializer
	 * @param futureContainer
	 * @param serverAddress
	 * @param connectCount
	 */
	NettyClientConnector(EventLoopGroup eventLoopGroup, //
			Serializer serializer, //
			HostPort serverAddress, int connectCount) {
		this.eventLoopGroup = eventLoopGroup;
		this.connectCount = connectCount;
		this.serverAddress = serverAddress;
		this.serializer = serializer;
	}

	int connectCount() {
		return connectCount;
	}

	/**
	 * 
	 * @param channelIndex
	 *            发送数据的channel
	 * 
	 * @param request
	 *            请求数据
	 */
	void send(int channelIndex, RequestWithFuture requestWithFuture) {
		Objects.requireNonNull(requestWithFuture, "request is null");

		Channel channel = channels[channelIndex];
		channel.writeAndFlush(requestWithFuture, channel.voidPromise());
	}

	void connect() throws InterruptedException {

		Bootstrap bootstrap = new Bootstrap();
		bootstrap.group(eventLoopGroup);

		bootstrap.option(ChannelOption.SO_REUSEADDR, true);
		bootstrap.option(ChannelOption.SO_RCVBUF, 256 * 1024);
		bootstrap.option(ChannelOption.SO_SNDBUF, 256 * 1024);
		bootstrap.option(ChannelOption.WRITE_BUFFER_WATER_MARK, //
				new WriteBufferWaterMark(1024 * 1024, 2048 * 1024));

		if (eventLoopGroup instanceof EpollEventLoopGroup) {
			bootstrap.option(EpollChannelOption.SO_REUSEPORT, true);
			bootstrap.channel(EpollSocketChannel.class);
		} else if (eventLoopGroup instanceof NioEventLoopGroup) {
			bootstrap.channel(NioSocketChannel.class);
		}

		bootstrap.handler(new TurboChannelInitializer(serializer));

		Channel[] newChannels = new Channel[connectCount];
		for (int i = 0; i < connectCount; i++) {
			newChannels[i] = bootstrap.connect(serverAddress.host, serverAddress.port).sync().channel();

			if (logger.isInfoEnabled()) {
				logger.info(serverAddress + " connect " + i + "/" + connectCount);
			}
		}

		InetSocketAddress insocket = (InetSocketAddress) newChannels[0].localAddress();
		clientAddress = new HostPort(insocket.getAddress().getHostAddress(), 0);

		Channel[] old = channels;
		channels = newChannels;

		if (old != null) {
			for (int i = 0; i < old.length; i++) {
				try {
					old[i].close();
				} catch (Exception e) {
					if (logger.isWarnEnabled()) {
						logger.warn("关闭出错", e);
					}
				}
			}
		}
	}

	@Override
	public void close() throws IOException {

		if (channels == null) {
			return;
		}

		for (int i = 0; i < channels.length; i++) {
			try {
				channels[i].close();
			} catch (Exception e) {
				if (logger.isWarnEnabled()) {
					logger.warn("关闭出错", e);
				}
			}
		}

		channels = null;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy