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

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

The 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;
import rpc.turbo.transport.client.sender.BatchSender;
import rpc.turbo.transport.client.sender.Sender;

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

	public static final int MAX_SEND_BUFFER_SIZE = 1024;

	public final HostPort serverAddress;

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

	public volatile HostPort clientAddress;
	private volatile Sender[] senders;

	/**
	 * 
	 * @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 requestWithFuture
	 *            请求数据
	 */
	void send(int channelIndex, RequestWithFuture requestWithFuture) {
		Objects.requireNonNull(requestWithFuture, "request is null");
		senders[channelIndex].send(requestWithFuture);
	}

	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));

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

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

			if (i == 0) {
				InetSocketAddress insocket = (InetSocketAddress) channel.localAddress();
				clientAddress = new HostPort(insocket.getAddress().getHostAddress(), 0);
			}
		}

		Sender[] old = senders;
		senders = newSenders;

		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 (senders == null) {
			return;
		}

		final Sender[] senders = this.senders;
		this.senders = null;

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

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy