   (proxy [SimpleChannelInboundHandler]
     []
     (channelActive [^ChannelHandlerContext ctx]
-      (info "active")
       ;(.writeAndFlush ctx (Unpooled/copiedBuffer "Netty Rocks1" CharsetUtil/UTF_8))
       )
     (channelRead0 [^ChannelHandlerContext ctx ^ByteBuf in]

      (>!! read-ch (buffer->bytes in))
      )
    (exceptionCaught [^ChannelHandlerContext ctx cause]
      (error cause (>!! [cause ctx]) )
      (.close ctx))))
    



(defn- do-write [^Client client ^bytes v close-after-write {:keys [error-ch] :as conf}]
  "Writes to the channel, this operation is non blocking and a exception listener is added to the write's ChannelFuture
   to send any errors to the error-ch"
  (try 
    (do 
     (let [ch-f (-> client ^ChannelFuture (:channel-f) ^Channel (.channel) ^ChannelFuture (.writeAndFlush v) (.addListener ^ChannelFutureListener (exception-listener v conf)))]
       (if close-after-write
         (.addListener ch-f ^ChannelFutureListener (close-listener client conf)))))
     (catch Exception e (do 
                          (error (str "Error in do-write " e) e)
                          (>!! error-ch [e v])
                          ))))


(defn start-client [host port {:keys [group read-ch error-ch write-ch handlers] :as conf 
                                 :or {group (NioEventLoopGroup.) read-ch (chan 100) error-ch (chan 100) write-ch (chan 100)}}]
  "Start a Client instance with read-ch, write-ch and error-ch"
  (try
  (let [g (if group group (NioEventLoopGroup.))
        b (Bootstrap.)]
    (-> b (.group g)
      ^Bootstrap (.channel NioSocketChannel)
      ^Bootstrap (.remoteAddress (InetSocketAddress. host port))
      ^Bootstrap (.handler ^ChannelInitializer (client-channel-initializer conf)))
    (let [ch-f (.connect b)]
      (.sync ch-f)
      (->Client g ch-f write-ch read-ch error-ch (AtomicInteger.))))
  (catch Exception e (do
                       (error (str "Error starting client " e) e)
                       (>!! error-ch [e nil])
                       ))))
    
(defn read-print-ch [n ch]
  (go 
    (loop [ch1 ch]
      (let [c (<! ch1)]
         (if (instance? Reconnected c)
           (do 
             ;(info "Reconnected " (:cause c) " ch1 " ch1 " new ch " (-> c :client :read-ch))
             (recur (-> c :client :read-ch)))
           (do 
             (info n " = " c)
             (recur ch1)))))))

(defn read-print-in [{:keys [read-ch]}]
  (read-print-ch "read" read-ch))


(defn client [host port {:keys [handlers
                                  retry-limit
                                  write-buff read-buff error-buff
                                  write-timeout read-timeout] 
                           :or {handlers [byte-encoder] retry-limit 10
                                write-buff 100 read-buff 100 error-buff 1000 reuse-client false write-timeout 1500 read-timeout 1500} }]
  (let [ write-ch (chan write-buff) 
         read-ch (chan read-buff)
