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

com.sm.transport.netty.TCPClient Maven / Gradle / Ivy

The newest version!
/*
 *
 *  * Copyright 2012-2015 Viant.
 *  *
 *  * 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.sm.transport.netty;

import com.sm.message.Request;
import com.sm.message.Response;
import com.sm.transport.Client;
import com.sm.transport.ConnectionException;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.*;
import org.jboss.netty.channel.socket.ClientSocketChannelFactory;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.channel.socket.oio.OioClientSocketChannelFactory;
import org.jboss.netty.handler.codec.frame.FrameDecoder;

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

public class TCPClient implements Client {
    private String host;
    private int port;
    private ChannelFuture future;
    private ClientBootstrap bootstrap;
    private ChannelUpstreamHandler clientHandler;
    // default for 5 seconds
    public final static long TIME_OUT = 5000L;


    private TCPClient(String host, int port) {
        this.host = host;
        this.port = port;
    }

    public String getHost() {
        return host;
    }

    public int getPort() {
        return port;
    }

    public ChannelFuture getFuture() {
        return future;
    }

    public ClientBootstrap getBootstrap() {
        return bootstrap;
    }

    /**
     *
     * @param host
     * @param port
     * @param clientHandler
     * @param encoder
     * @param decoder must be thread safe
     * @return
     */
    public static TCPClient start(String host, int port, final ChannelUpstreamHandler clientHandler, final ChannelDownstreamHandler encoder,
                                  final FrameDecoder decoder){
        return start(host, port, clientHandler, encoder, decoder, true);

    }

    /**
     * Use nonSharableChannelPipeline which create a decoder for each connection
     * @param host
     * @param port
     * @param clientHandler
     * @return
     */
    public static TCPClient start(String host, int port, final ChannelUpstreamHandler clientHandler ){
        //return start(host, port, clientHandler, new Encoder(), new Decoder());
        return start(host, port, true, clientHandler, nonSharableChannelPipelineFactory(clientHandler, new Encoder()));
    }

    /**
     * Use nonSharableChannelPipeline which create a decoder for each connection
     * @param host
     * @param port
     * @param clientHandler
     * @return
     */
    public static TCPClient startOio(String host, int port, final ChannelUpstreamHandler clientHandler ){
        //return startOio(host, port, clientHandler, new Encoder(), new Decoder());
        return start(host, port, false, clientHandler, nonSharableChannelPipelineFactory(clientHandler, new Encoder()));
    }

    /**
     *
     * @param host
     * @param port
     * @param clientHandler
     * @param encoder
     * @param decoder must be thread safe
     * @return
     */
    public static TCPClient startOio(String host, int port, final ChannelUpstreamHandler clientHandler, final ChannelDownstreamHandler encoder,
                                  final FrameDecoder decoder){
        return start( host, port, clientHandler, encoder, decoder, false);


    }

    private static TCPClient start(String host, int port, final boolean nio,final ChannelUpstreamHandler clientHandler, final ChannelPipelineFactory factory ) {
        TCPClient client = new TCPClient(host, port);
        client.clientHandler= clientHandler;
        // Configure the client.
        client.bootstrap = new ClientBootstrap( getClientSocketChannelFactory(nio));
        client.bootstrap.setPipelineFactory( nonSharableChannelPipelineFactory( clientHandler, new Encoder()));
        // Start the connection attempt.
        client.future = client.bootstrap.connect(new InetSocketAddress(host, port));
        if (client.getFuture().awaitUninterruptibly(TIME_OUT) && client.getFuture().getChannel().isConnected())
            return client ; //logger.info("wait ok");
        else {
            client.future.getChannel().close();
            client.bootstrap.releaseExternalResources();
            throw new ConnectionException("not able to connect "+ client.toString());
        }
    }

    private static TCPClient start(String host, int port, final ChannelUpstreamHandler clientHandler, final ChannelDownstreamHandler encoder,
                              final FrameDecoder decoder, boolean nio){
        TCPClient client = new TCPClient(host, port);
        client.clientHandler= clientHandler;
        // Configure the client.
        client.bootstrap = new ClientBootstrap( getClientSocketChannelFactory(nio));
        // Set up the pipeline factory.
        client.bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
            public ChannelPipeline getPipeline() throws Exception {
                return Channels.pipeline(
                        encoder,
                        decoder,
                        clientHandler);
            }
        });

        // Start the connection attempt.
        client.future = client.bootstrap.connect(new InetSocketAddress(host, port));
        if (client.getFuture().awaitUninterruptibly(TIME_OUT) && client.getFuture().getChannel().isConnected())
            return client ; //logger.info("wait ok");
        else {
            client.future.getChannel().close();
            client.bootstrap.releaseExternalResources();
            throw new ConnectionException("not able to connect "+ client.toString());
        }

    }

    private static ChannelPipelineFactory nonSharableChannelPipelineFactory( final ChannelUpstreamHandler clientHandler,
                                                                             final Encoder encoder) {
        return new ChannelPipelineFactory() {
            public ChannelPipeline getPipeline() throws Exception {
                return Channels.pipeline(
                        encoder,
                        new Decoder(),
                        clientHandler);
            }
        };
    }

    private static ClientSocketChannelFactory getClientSocketChannelFactory(boolean nio) {
        if ( nio)
            return new NioClientSocketChannelFactory(
                    Executors.newCachedThreadPool(),
                    Executors.newCachedThreadPool());
        else
            return new OioClientSocketChannelFactory(
                    Executors.newCachedThreadPool());
    }

    public static TCPClient start(String host, int port, final ChannelUpstreamHandler clientHandler, byte version) {
        //return start(host, port, clientHandler, new Encoder(version), new Decoder(version));
        return start(host, port, true, clientHandler, nonSharableChannelPipelineFactory(clientHandler, new Encoder(version)));
    }

    public static TCPClient start(String host, int port){
        return start(host, port, new ClientAsynHandler());
    }

    public boolean isConnected() {
        //switch from isOpen()
        return future.getChannel().isConnected() ;
    }

    public Client reconnect() {
        future = bootstrap.connect(new InetSocketAddress(host, port));
        if (future.awaitUninterruptibly(TIME_OUT) && isConnected())
            return this ;
        else
            return null;
    }

    public ChannelUpstreamHandler getClientHandler() {
        return clientHandler;
    }

    public Response sendRequest(Request request) {
        //if ( request.getType() == Request.RequestType.Async ) throw new RuntimeException("sendRequest did not support asynchronized call ");
        return ((Send) clientHandler).sendRequest( request, future.getChannel() );
    }

    public void sendMessage(Request request) {
        if (  request.getType() != Request.RequestType.Async ) throw new RuntimeException("sendMessage support async call");
        future.getChannel().write( request);
    }

    public Response invoke(Request request) {
         return ((Send) clientHandler).invoke( request, future.getChannel() );
    }

    public void close() {
        future.getChannel().close();
    }

    public void shutdown() {
        bootstrap.shutdown();
        bootstrap.releaseExternalResources();
    }

    @Override
    public boolean equals(Object client) {
        if ( client == null ) return false;
        else {

            if (! ( client instanceof TCPClient) ) return false;
            if ( ((TCPClient) client).getPort() == port && ((TCPClient)client).getHost().equals( host ))
                return true;
            else
                return false;
        }
    }

    @Override
    public String toString() {
        return host+" "+port;
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy