                         }})
          {:status 400
           :headers {}
-          :body "websocket expected"}))))+          :body "Websocket expected"}))))
  (let [h (RingHandler. thread handler worker-name-prefix)
        s (HttpServer. ip port h max-body max-line)]
    (.start s)
    ;; return a function to stop this server
    (fn [] (.close h) (.stop s))))

(defmacro defasync [name [req] cb & body]
  `(defn ~name [~req]
     {:status 200
      :headers {}
      :body (let [data# (atom {})
                  ~cb (fn [resp#]
                        (reset! data# (assoc @data# :r resp#))
                        (when-let [l# ^Runnable (:l @data#)]
                          (.run l#)))]
              (do ~@body)
              (reify IListenableFuture
                (addListener [this# listener#]
                  (if-let [d# (:r @data#)]
                    (.run ^Runnable listener#)
                    (reset! data# (assoc @data# :l listener#))))
                (get [this#]
                  (:r @data#))))}))

(defn on-mesg   [^WsCon con fn]  (.addRecieveListener con fn))
(defn on-close  [^WsCon con fn]  (.addOnCloseListener con fn))
(defn send-mesg [^WsCon con msg] (.send con msg))
(defn close-conn
  ([con]        (.serverClose ^WsCon con))
  ([con status] (.serverClose ^WsCon con status)))

(defmacro defwshandler [name [req] con & body]
  `(defn ~name [~req]
     (let [~con (:websocket ~req)
           key# (get-in ~req [:headers "sec-websocket-key"])]
       (if (and ~con key#)
         (do ~@body
             {:status 101
              :headers {"Upgrade" "websocket"

           javax.xml.bind.DatatypeConverter
           java.security.MessageDigest))

;;;; Ring server

(defn run-server
  [handler {:keys [port thread ip max-body max-line worker-name-prefix]
