 
 (defn websocket-send [socket type & message-args]
   {:pre [(instance? WebsocketChannel socket)]}
-  (let [seq-args ((:sequencer socket) type message-args)]
-    (enqueue (:channel socket)
+  (let [seq-args ((:sequencer socket) type message-args)
+        channel (:channel socket)
+        endpoint (:endpoint socket)
+        {:keys [id callback]} seq-args]
+    (when (and callback id)
+      (receive (->> channel
+                    (map* translate-message)
+                    (filter* #(= :ack (first %1))) ; [type _ _ _ _]
+                    (map* #(translate-ack (last %1))) ; [_ _ _ _ data]
+                    (filter* #(= id (first %1))) ; [id data]
+                    (map* second)) 
+               callback))
+    (enqueue channel
              (apply websocket-message type
-                    (into seq-args [:endpoint (:endpoint socket)])))
-    (:id seq-args)))
+                    (into seq-args [:endpoint endpoint])))))
 
 (defn websocket-sequencer []
   (let [counter (atom 0)]
     (fn [type message]
-      (if (#{:message :json-message :event} (message-types type))
+      (if (#{:message :json-message :event} type)
         (concat message [:id (swap! counter inc)])
         message))))
 

(defn translate-message-type [type]
  (message-types (Integer/parseInt type)))

(defmulti websocket-message (fn [type & rest] (class type)))
(defmethod websocket-message Integer
  [type & {:keys [id endpoint data] :or {id "" endpoint ""}}]

(defn send-heartbeat [socket]
  (websocket-send socket :heartbeat))

(defn send-message
  ([socket data] (websocket-send socket :message :data (message data)))
  ([socket data callback] (websocket-send socket :message :data (message data) :callback callback)))

(defn send-event
  ([socket name args]
     (websocket-send socket :event :data (encode-json->string {:name name :args args})))
  ([socket name args callback]
     (websocket-send socket :event :data (encode-json->string {:name name :args args})
                     :callback callback)))

(defn send-ack
  ([socket id] (websocket-send socket :ack :data (str id)))
