Nikita made a good library
[net.async/async "0.1.0"] for asynchronous network communication.
https://github.com/tonsky/net.async
Just add this to your project.clj
[org.clojure/clojure "1.8.0"]
;; async network communications
[net.async/async "0.1.0" :exclusions [[org.clojure/clojure]
[org.clojure/tools.logging]
[org.clojure/core.async]]]
[org.clojure/core.async "0.3.443" :exclusions [org.clojure/tools.reader]]
[org.clojure/tools.logging "0.4.0"]
Here is an output of example below:
-------------------------------
server: 4263
client: ECHO/4263
-------------------------------
server: 16640
client: ECHO/16640
-------------------------------
server: 75968
client: ECHO/75968
-------------------------------
server: 11092
client: ECHO/11092
-------------------------------
server: 61707
client: ECHO/61707
-------------------------------
server: 50773
client: ECHO/50773
-------------------------------
server: 16803
client: ECHO/16803
-------------------------------
Here is a source code of echo server and client:
(require '[clojure.core.async :refer [<! >! <!! >!! close! go]])
(use 'net.async.tcp)
(def event-l-client (event-loop))
(def event-l-server (event-loop))
(defn echo-server [evt-loop]
(let [acceptor (accept evt-loop {:port 8899})]
(loop []
(when-let [server (<!! (:accept-chan acceptor))]
(go
(loop []
(when-let [msg (<! (:read-chan server))]
(when-not (keyword? msg)
(>! (:write-chan server) (.getBytes (str "ECHO/" (String. msg))))
(println "server: " (String. msg)))
(recur))))
(recur)))))
(defn echo-client [evt-loop]
(let [client (connect evt-loop {:host "127.0.0.1" :port 8899})]
(loop []
(go (>! (:write-chan client) (.getBytes (str (rand-int 100000)))))
(loop []
(let [read (<!! (:read-chan client))]
(when (bytes? read) (println "client: " (String. read)))
(when (and (keyword? read)
(not= :connected read))
(println "disconnected from server. trying to reconnect using timeout")
(recur))))
(println "-------------------------------")
(Thread/sleep (rand-int 3000))
(recur))))
(future (echo-server event-l-server))
(future (echo-client event-l-client))
(shutdown! event-l-server)
(shutdown! event-l-client)