tp.Client.java Source code

Java tutorial

Introduction

Here is the source code for tp.Client.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package tp;

import classes.Reply;
import com.fasterxml.uuid.Generators;
import interfaces.ConnectionFeedBack;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import object.client.ext.ReConnectManager;
import object.client.ext.States;
import object.client.ext.TryConnectException;

/**
 *
 * @author Tareq
 */
public class Client {

    private final String remotehost;
    private final int port;
    private final static EventLoopGroup GROUP = new NioEventLoopGroup();
    private final Bootstrap bootstrap;
    private final AtomicReference<Channel> channel = new AtomicReference<>(null);
    private final Map<String, Reply> replies;
    //private int tryCount = 0;
    //private final int maxTryCount = 99;
    private final ConnectionFeedBack connectionFeedBack;
    private States.ConnectioState connectioState = States.ConnectioState.nil;
    private final ExecutorService EXECUTOR = Executors.newFixedThreadPool(1);
    private final AtomicBoolean reTryFlag = new AtomicBoolean(true);
    private ReConnectManager<Client> reConnectManager;

    public static class Monitor extends Thread {

        private final BlockingQueue<States.ConnectioState> queue = new LinkedBlockingQueue();

        public Monitor() {
            super("Monitor Thraed");
        }

        @Override
        public void run() {
            while (!this.isInterrupted()) {
                try {
                    States.ConnectioState cs = queue.take();
                    System.out.println("now it is : " + cs.name());
                } catch (InterruptedException ex) {
                    System.out.println("[Error] " + ex.getMessage());
                }
            }
        }

        public void state(States.ConnectioState connectioState) {
            queue.add(connectioState);
        }
    }

    public void stopRetry() {
        reTryFlag.set(false);
    }

    public Client(String remotehost, int port, ConnectionFeedBack connectionFeedBack) {
        //int processors = Runtime.getRuntime().availableProcessors();
        //pool = Executors.newFixedThreadPool(processors);
        this.connectionFeedBack = connectionFeedBack;
        //uniqueId = new UniqueId();
        this.remotehost = remotehost;
        this.port = port;

        bootstrap = new Bootstrap();
        bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 2000);
        replies = new ConcurrentHashMap();
        //ini();
    }

    private void init(ConnectionFeedBack cfb) {
        bootstrap.group(GROUP).channel(NioSocketChannel.class).handler(new NettyClientInitializer(replies, cfb));
    }

    public void setConnectioState(States.ConnectioState connectioState) {
        this.connectioState = connectioState;
    }

    public void setup() {
        //monitor.start();
        ConnectionFeedBack cfb = setupConnectionFeedBack();
        init(cfb);
        reConnectManager = new ReConnectManager(this, 5000L);
    }

    public void connectMe() {
        CompletableFuture<Channel> future = CompletableFuture.supplyAsync(() -> {
            return connect();
        }, EXECUTOR).whenComplete((result, ex) -> {
            if (result != null) {
                channel.set(result);
            } else {
                channel.set(null);
            }
        });
        future.join();
    }

    public void start() {
        reConnectManager.resume();
    }

    private Channel connect() {
        try {
            //System.out.println("[connectioState] " + connectioState.name());
            //System.out.println("Try to Connect on : " + remotehost + ":" + port);
            CompletableFuture<Channel> futureResult = new CompletableFuture<>();
            ChannelFuture future = bootstrap.connect(remotehost, port);
            future.addListener((ChannelFutureListener) (ChannelFuture future1) -> {
                if (future1.isSuccess()) {
                    futureResult.complete(future1.channel());
                } else {
                    futureResult.completeExceptionally(new TryConnectException(remotehost, port));
                }
            });
            future.awaitUninterruptibly();
            return futureResult.join();
        } catch (Exception ex) {
            return null;
        }
    }

    private ConnectionFeedBack setupConnectionFeedBack() {
        ConnectionFeedBack cfb = new ConnectionFeedBack() {
            @Override
            public void connectionActive() {
                setConnectioState(States.ConnectioState.connected);
                reConnectManager.setConnected(true);
                connectionFeedBack.connectionActive();

            }

            @Override
            public void connectionClosed() {
                setConnectioState(States.ConnectioState.disconected);
                reConnectManager.setConnected(false);
                connectionFeedBack.connectionClosed();
                if (reTryFlag.get()) {
                    connectionFeedBack.onTryToConnect();
                }
            }

            @Override
            public void connectionException(Throwable cause) {
                setConnectioState(States.ConnectioState.disconected);
                connectionFeedBack.connectionException(cause);
            }

            @Override
            public void onRecivedError(Throwable cause) {
                connectionFeedBack.onRecivedError(cause);
            }

            @Override
            public void onRecivedData(Object message, Channel channel) {
                connectionFeedBack.onRecivedData(message, channel);
            }
        };
        return cfb;
    }

    public States.ConnectioState getConnectioState() {
        return connectioState;
    }

    public String send(String msg) {
        String filter = msg.replace("\n", "").replace("\r", "");
        //final int id = uniqueId.getUniqueId();
        final String id = Generators.randomBasedGenerator().generate().toString();
        replies.put(id, new Reply());
        String m = filter.replaceAll(">\\s*<", "><");//encryption.encrypt(id+msg);//
        channel.get().writeAndFlush(id + m + "\r\n");
        return id;
    }

    public CompletableFuture<Boolean> sendwithoutRply(final String msg, final int timeout, final TimeUnit tu) {
        //CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
        final CompletableFuture<Boolean> statefuture = new CompletableFuture<>();
        String filter = msg.replace("\n", "").replace("\r", "");
        //final int id = uniqueId.getUniqueId();
        final String id = Generators.randomBasedGenerator().generate().toString();
        final Reply r = new Reply();
        //System.err.println(msg);
        //replies.put(id, r);
        String m = filter.replaceAll(">\\s*<", "><");//encryption.encrypt(id+msg);//
        m = m.replaceAll("(&(?!amp;))", "&amp;");
        m = m.trim();
        final String finalMsg = id + m + "\r\n";
        channel.get().writeAndFlush(finalMsg).addListener((ChannelFutureListener) (ChannelFuture future) -> {
            if (future.isSuccess()) {
                statefuture.complete(true);
            } else {

                //System.err.println("[Error][unable to send msg] " + finalMsg);
                statefuture.complete(false);
            }
        });
        return statefuture;
    }

    public CompletableFuture<String> sendwithRplyInFuture(final String msg, final int timeout, final TimeUnit tu) {
        CompletableFuture<String> result = new CompletableFuture<>();
        String filter = msg.replace("\n", "").replace("\r", "");
        //final int id = uniqueId.getUniqueId();
        final String id = Generators.randomBasedGenerator().generate().toString();
        final Reply r = new Reply();
        r.setResult(result);
        //System.err.println(msg);
        replies.put(id, r);
        String m = filter.replaceAll(">\\s*<", "><");//encryption.encrypt(id+msg);//
        m = m.replaceAll("(&(?!amp;))", "&amp;");
        m = m.trim();
        channel.get().writeAndFlush(id + m + "\r\n");
        return result;
    }

    public CompletableFuture<String> sendwithRply(final String msg, final int timeout, final TimeUnit tu) {
        CompletableFuture<String> result = new CompletableFuture<>();
        //CompletableFuture<String> future = new CompletableFuture<>();
        String filter = msg.replace("\n", "").replace("\r", "");
        //final int id = uniqueId.getUniqueId();
        final String id = Generators.randomBasedGenerator().generate().toString();
        final Reply r = new Reply();
        r.setResult(result);
        //System.err.println(msg);
        replies.put(id, r);
        String m = filter.replaceAll(">\\s*<", "><");//encryption.encrypt(id+msg);//
        m = m.replaceAll("(&(?!amp;))", "&amp;");
        m = m.trim();
        channel.get().writeAndFlush(id + m + "\r\n");
        return result;
    }

    public void shutdown() {
        reConnectManager.cancel();

        GROUP.shutdownGracefully();
    }

    public void close() {
        channel.get().close();
    }

    public String getHost() {
        return remotehost;
    }

    public int getPort() {
        return port;
    }

    public boolean isConnected() {
        return channel.get().isOpen();
    }

    public Channel getChannel() {
        return channel.get();
    }

    public Map<String, Reply> getReplies() {
        return replies;
    }

}