com.googlecode.protobuf.pro.duplex.example.simple.SimpleClient.java Source code

Java tutorial

Introduction

Here is the source code for com.googlecode.protobuf.pro.duplex.example.simple.SimpleClient.java

Source

/**
 *   Copyright 2010-2014 Peter Klauser
 *
 *   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.googlecode.protobuf.pro.duplex.example.simple;

import io.netty.bootstrap.Bootstrap;
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.concurrent.Executors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.protobuf.ByteString;
import com.google.protobuf.ExtensionRegistry;
import com.google.protobuf.ServiceException;
import com.googlecode.protobuf.pro.duplex.CleanShutdownHandler;
import com.googlecode.protobuf.pro.duplex.ClientRpcController;
import com.googlecode.protobuf.pro.duplex.PeerInfo;
import com.googlecode.protobuf.pro.duplex.RpcClientChannel;
import com.googlecode.protobuf.pro.duplex.RpcConnectionEventNotifier;
import com.googlecode.protobuf.pro.duplex.client.DuplexTcpClientPipelineFactory;
import com.googlecode.protobuf.pro.duplex.client.RpcClientConnectionWatchdog;
import com.googlecode.protobuf.pro.duplex.example.wire.PingPong;
import com.googlecode.protobuf.pro.duplex.example.wire.PingPong.BlockingPingService;
import com.googlecode.protobuf.pro.duplex.example.wire.PingPong.ExtendedPing;
import com.googlecode.protobuf.pro.duplex.example.wire.PingPong.ExtendedPong;
import com.googlecode.protobuf.pro.duplex.example.wire.PingPong.Ping;
import com.googlecode.protobuf.pro.duplex.example.wire.PingPong.Pong;
import com.googlecode.protobuf.pro.duplex.execute.RpcServerCallExecutor;
import com.googlecode.protobuf.pro.duplex.execute.ThreadPoolCallExecutor;
import com.googlecode.protobuf.pro.duplex.listener.RpcConnectionEventListener;
import com.googlecode.protobuf.pro.duplex.logging.CategoryPerServiceLogger;
import com.googlecode.protobuf.pro.duplex.util.RenamingThreadFactoryProxy;

public class SimpleClient {

    private static Logger log = LoggerFactory.getLogger(SimpleClient.class);

    private static RpcClientChannel channel = null;

    public static void main(String[] args) throws Exception {
        if (args.length != 4) {
            System.err.println("usage: <serverHostname> <serverPort> <clientHostname> <clientPort>");
            System.exit(-1);
        }
        String serverHostname = args[0];
        int serverPort = Integer.parseInt(args[1]);
        String clientHostname = args[2];
        int clientPort = Integer.parseInt(args[3]);

        PeerInfo client = new PeerInfo(clientHostname, clientPort);
        PeerInfo server = new PeerInfo(serverHostname, serverPort);

        try {
            DuplexTcpClientPipelineFactory clientFactory = new DuplexTcpClientPipelineFactory();
            // force the use of a local port
            // - normally you don't need this
            clientFactory.setClientInfo(client);

            ExtensionRegistry r = ExtensionRegistry.newInstance();
            PingPong.registerAllExtensions(r);
            clientFactory.setExtensionRegistry(r);

            clientFactory.setConnectResponseTimeoutMillis(10000);
            RpcServerCallExecutor rpcExecutor = new ThreadPoolCallExecutor(3, 10);
            clientFactory.setRpcServerCallExecutor(rpcExecutor);

            // RPC payloads are uncompressed when logged - so reduce logging
            CategoryPerServiceLogger logger = new CategoryPerServiceLogger();
            logger.setLogRequestProto(false);
            logger.setLogResponseProto(false);
            clientFactory.setRpcLogger(logger);

            // Set up the event pipeline factory.
            // setup a RPC event listener - it just logs what happens
            RpcConnectionEventNotifier rpcEventNotifier = new RpcConnectionEventNotifier();

            final RpcConnectionEventListener listener = new RpcConnectionEventListener() {

                @Override
                public void connectionReestablished(RpcClientChannel clientChannel) {
                    log.info("connectionReestablished " + clientChannel);
                    channel = clientChannel;
                }

                @Override
                public void connectionOpened(RpcClientChannel clientChannel) {
                    log.info("connectionOpened " + clientChannel);
                    channel = clientChannel;
                }

                @Override
                public void connectionLost(RpcClientChannel clientChannel) {
                    log.info("connectionLost " + clientChannel);
                }

                @Override
                public void connectionChanged(RpcClientChannel clientChannel) {
                    log.info("connectionChanged " + clientChannel);
                    channel = clientChannel;
                }
            };
            rpcEventNotifier.addEventListener(listener);
            clientFactory.registerConnectionEventListener(rpcEventNotifier);

            Bootstrap bootstrap = new Bootstrap();
            EventLoopGroup workers = new NioEventLoopGroup(16,
                    new RenamingThreadFactoryProxy("workers", Executors.defaultThreadFactory()));

            bootstrap.group(workers);
            bootstrap.handler(clientFactory);
            bootstrap.channel(NioSocketChannel.class);
            bootstrap.option(ChannelOption.TCP_NODELAY, true);
            bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000);
            bootstrap.option(ChannelOption.SO_SNDBUF, 1048576);
            bootstrap.option(ChannelOption.SO_RCVBUF, 1048576);

            RpcClientConnectionWatchdog watchdog = new RpcClientConnectionWatchdog(clientFactory, bootstrap);
            rpcEventNotifier.addEventListener(watchdog);
            watchdog.start();

            CleanShutdownHandler shutdownHandler = new CleanShutdownHandler();
            shutdownHandler.addResource(workers);
            shutdownHandler.addResource(rpcExecutor);

            clientFactory.peerWith(server, bootstrap);

            while (true && channel != null) {

                BlockingPingService.BlockingInterface blockingService = BlockingPingService
                        .newBlockingStub(channel);
                final ClientRpcController controller = channel.newRpcController();
                controller.setTimeoutMs(0);

                Ping.Builder pingBuilder = Ping.newBuilder();
                pingBuilder.setSequenceNo(1);
                pingBuilder.setPingDurationMs(1000);
                pingBuilder.setPingPayload(ByteString.copyFromUtf8("Hello World!"));
                pingBuilder.setPingPercentComplete(false);
                pingBuilder.setPongRequired(false);
                pingBuilder.setPongBlocking(true);
                pingBuilder.setPongDurationMs(1000);
                pingBuilder.setPongTimeoutMs(0);
                pingBuilder.setPongPercentComplete(false);

                // set an extension value
                pingBuilder.setExtension(ExtendedPing.extendedIntField, 111);

                Ping ping = pingBuilder.build();
                try {
                    Pong pong = blockingService.ping(controller, ping);

                    Integer ext = pong.getExtension(ExtendedPong.extendedIntField);
                    if (ext == null || ext != 111) {
                        log.warn("Extension not parsed. Value=", ext);
                    }
                } catch (ServiceException e) {
                    log.warn("Call failed.", e);
                }

                Thread.sleep(10000);

            }

        } catch (Exception e) {
            log.warn("Failure.", e);
        } finally {
            System.exit(0);
        }
    }

}