/* * Copyright 1999-2011 Alibaba Group. * * 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.alibaba.dubbo.remoting.transport.grizzly; import java.util.concurrent.TimeUnit; import org.glassfish.grizzly.Connection; import org.glassfish.grizzly.filterchain.FilterChainBuilder; import org.glassfish.grizzly.filterchain.TransportFilter; import org.glassfish.grizzly.nio.transport.TCPNIOTransport; import org.glassfish.grizzly.nio.transport.TCPNIOTransportBuilder; import org.glassfish.grizzly.strategies.SameThreadIOStrategy; import org.glassfish.grizzly.threadpool.ThreadPoolConfig; import com.alibaba.dubbo.common.Constants; import com.alibaba.dubbo.common.URL; import com.alibaba.dubbo.common.logger.Logger; import com.alibaba.dubbo.common.logger.LoggerFactory; import com.alibaba.dubbo.remoting.Channel; import com.alibaba.dubbo.remoting.ChannelHandler; import com.alibaba.dubbo.remoting.RemotingException; import com.alibaba.dubbo.remoting.transport.AbstractClient; /** * GrizzlyClient * * @author william.liangf */ public class GrizzlyClient extends AbstractClient { private static final Logger logger = LoggerFactory.getLogger(GrizzlyClient.class); private TCPNIOTransport transport; private volatile Connection<?> connection; // volatile, please copy reference to use public GrizzlyClient(URL url, ChannelHandler handler) throws RemotingException { super(url, handler); } @Override protected void doOpen() throws Throwable { FilterChainBuilder filterChainBuilder = FilterChainBuilder.stateless(); filterChainBuilder.add(new TransportFilter()); filterChainBuilder.add(new GrizzlyCodecAdapter(getCodec(), getUrl(), this)); filterChainBuilder.add(new GrizzlyHandler(getUrl(), this)); TCPNIOTransportBuilder builder = TCPNIOTransportBuilder.newInstance(); ThreadPoolConfig config = builder.getWorkerThreadPoolConfig(); config.setPoolName(CLIENT_THREAD_POOL_NAME) .setQueueLimit(-1) .setCorePoolSize(0) .setMaxPoolSize(Integer.MAX_VALUE) .setKeepAliveTime(60L, TimeUnit.SECONDS); builder.setTcpNoDelay(true).setKeepAlive(true) .setConnectionTimeout(getTimeout()) .setIOStrategy(SameThreadIOStrategy.getInstance()); transport = builder.build(); transport.setProcessor(filterChainBuilder.build()); transport.start(); } @Override protected void doConnect() throws Throwable { connection = transport.connect(getConnectAddress()) .get(getUrl().getPositiveParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS); } @Override protected void doDisConnect() throws Throwable { try { GrizzlyChannel.removeChannelIfDisconnectd(connection); } catch (Throwable t) { logger.warn(t.getMessage()); } } @Override protected void doClose() throws Throwable { try { transport.stop(); } catch (Throwable e) { logger.warn(e.getMessage(), e); } } @Override protected Channel getChannel() { Connection<?> c = connection; if (c == null || ! c.isOpen()) return null; return GrizzlyChannel.getOrAddChannel(c, getUrl(), this); } }