private String createConnectAddress() {
   String addrs;
   if (null != zmqOpts && null != zmqOpts.connectAddresses()) {
     addrs = zmqOpts.connectAddresses();
   } else {
     addrs = "tcp://" + getConnectAddress().getHostString() + ":" + getConnectAddress().getPort();
   }
   return addrs;
 }
  @Override
  protected Promise<Void> doStart(
      final ReactiveChannelHandler<Buffer, Buffer, ReactiveChannel<Buffer, Buffer>> handler) {
    final UUID id = UUIDUtils.random();

    final Promise<Void> p = Promises.ready();

    final int socketType = (null != zmqOpts ? zmqOpts.socketType() : ZMQ.DEALER);
    final ZContext zmq = (null != zmqOpts ? zmqOpts.context() : null);

    final Broadcaster<ZMsg> broadcaster = SerializedBroadcaster.create(getDefaultTimer());

    ZeroMQWorker worker =
        new ZeroMQWorker(id, socketType, ioThreadCount, zmq, broadcaster) {
          @Override
          protected void configure(ZMQ.Socket socket) {
            socket.setReceiveBufferSize(getOptions().rcvbuf());
            socket.setSendBufferSize(getOptions().sndbuf());
            if (getOptions().keepAlive()) {
              socket.setTCPKeepAlive(1);
            }
            if (null != zmqOpts && null != zmqOpts.socketConfigurer()) {
              zmqOpts.socketConfigurer().accept(socket);
            }
          }

          @Override
          @SuppressWarnings("unchecked")
          protected void start(final ZMQ.Socket socket) {
            try {
              String addr = createConnectAddress();
              if (log.isInfoEnabled()) {
                String type = ZeroMQ.findSocketTypeName(socket.getType());
                log.info("CONNECT: connecting ZeroMQ {} socket to {}", type, addr);
              }

              socket.connect(addr);

              final ZeroMQChannel netChannel =
                  bindChannel().setConnectionId(id.toString()).setSocket(socket);

              handler
                  .apply(netChannel)
                  .subscribe(
                      new DefaultSubscriber<Void>() {
                        @Override
                        public void onSubscribe(Subscription s) {
                          s.request(Long.MAX_VALUE);
                        }

                        @Override
                        public void onComplete() {
                          log.debug("Closing Client Worker " + id);
                          netChannel.close();
                        }

                        @Override
                        public void onError(Throwable t) {
                          log.error("Error during registration", t);
                          netChannel.close();
                        }
                      });

              broadcaster.consume(
                  new Consumer<ZMsg>() {
                    @Override
                    public void accept(ZMsg msg) {
                      ZFrame content;
                      while (null != (content = msg.pop())) {
                        netChannel.inputSub.onNext(Buffer.wrap(content.getData()));
                      }
                      msg.destroy();
                    }
                  });

              p.onComplete();
            } catch (Exception e) {
              p.onError(e);
            }
          }
        };
    threadPool.submit(worker);
    return p;
  }