Java tutorial
/* * Copyright 2002-2014 the original author or authors. * * 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 com.baidu.jprotobuf.pbrpc.transport; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelOption; import io.netty.channel.DefaultMessageSizeEstimator; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.util.HashedWheelTimer; import io.netty.util.Timer; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; /** * RPC client handler class. * * @author xiemalin * @author songhuiqing * @date 2013/03/07 10:30:20 * @version 1.0.0 */ public class RpcClient extends Bootstrap { /** * Tick count of each wheel instance for timer */ private static final int DEFAULT_TICKS_PER_WHEEL = 2048; /** * Tick duration for timer */ private static final int DEFAULT_TICK_DURATION = 100; // ?? private final Map<Long, RpcClientCallState> requestMap = new ConcurrentHashMap<Long, RpcClientCallState>(); private AtomicLong correlationId = new AtomicLong(1); // session private static Timer timer = createTimer(); // ? private RpcClientOptions rpcClientOptions; private ChannelPool channelPool; private NioEventLoopGroup workerGroup; private static final AtomicInteger INSTANCE_COUNT = new AtomicInteger(); private static Timer createTimer() { Timer timer = new HashedWheelTimer(Executors.defaultThreadFactory(), DEFAULT_TICK_DURATION, TimeUnit.MILLISECONDS, DEFAULT_TICKS_PER_WHEEL); return timer; } public RpcClient() { this(NioSocketChannel.class); } public RpcClient(RpcClientOptions rpcClientOptions) { this(NioSocketChannel.class, rpcClientOptions); } public RpcClient(Class<? extends Channel> clientChannelClass) { this(NioSocketChannel.class, new RpcClientOptions()); } public RpcClient(Class<? extends Channel> clientChannelClass, RpcClientOptions rpcClientOptions) { this.workerGroup = new NioEventLoopGroup(); this.group(workerGroup); this.channel(clientChannelClass); this.handler(new RpcClientPipelineinitializer(this)); this.rpcClientOptions = rpcClientOptions; this.option(ChannelOption.SO_REUSEADDR, rpcClientOptions.isReuseAddress()); this.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, rpcClientOptions.getConnectTimeout()); this.option(ChannelOption.SO_SNDBUF, rpcClientOptions.getSendBufferSize()); this.option(ChannelOption.SO_RCVBUF, rpcClientOptions.getSendBufferSize()); this.option(ChannelOption.SO_KEEPALIVE, rpcClientOptions.isKeepAlive()); this.option(ChannelOption.TCP_NODELAY, rpcClientOptions.getTcpNoDelay()); this.option(ChannelOption.MESSAGE_SIZE_ESTIMATOR, new DefaultMessageSizeEstimator(rpcClientOptions.getReceiveBufferSize())); // add count INSTANCE_COUNT.incrementAndGet(); } /** * @brief ? * @param seqId * @return RpcClientCallState * @author songhuiqing * @date 2013/03/07 10:34:30 */ public RpcClientCallState removePendingRequest(long seqId) { return requestMap.remove(seqId); } /** * @brief ? * @param seqId * @param state * @return void * @exception IllegalArgumentException * @author songhuiqing * @date 2013/03/07 10:34:30 */ public void registerPendingRequest(long seqId, RpcClientCallState state) { if (requestMap.containsKey(seqId)) { throw new IllegalArgumentException("State already registered"); } requestMap.put(seqId, state); } /** * @brief ?? * @return long * @author songhuiqing * @date 2013/03/07 10:33:20 */ public long getNextCorrelationId() { return correlationId.getAndIncrement(); } public Timer getTimer() { return timer; } public RpcClientOptions getRpcClientOptions() { return rpcClientOptions; } public void setRpcClientOptions(RpcClientOptions rpcClientOptions) { this.rpcClientOptions = rpcClientOptions; } /** * get the channelPool * * @return the channelPool */ protected ChannelPool getChannelPool() { return channelPool; } /** * set channelPool value to channelPool * * @param channelPool the channelPool to set */ protected void setChannelPool(ChannelPool channelPool) { this.channelPool = channelPool; } /* * (non-Javadoc) * * @see org.jboss.netty.bootstrap.Bootstrap#shutdown() */ public void shutdown() { if (this.workerGroup != null) { this.workerGroup.shutdownGracefully(); } if (channelPool != null) { channelPool.stop(); } // to check instance count int count = INSTANCE_COUNT.decrementAndGet(); if (count == 0) { // no current instance count try to stop old if (timer != null) { timer.stop(); // reset timer timer = createTimer(); // ? } } } /** * do shutdown action */ public void stop() { shutdown(); } }