Did you know that your familiar friend Jetty 7 (of ring-jetty-adapter fame) can talk websockets? This library provides a Jetty 7 configurator that exposes websockets as core.async channels.
Install | Server quick-start | Client quick-start | Example app | Thanks! | Similar libraries
Add to your project.clj
:
[com.keminglabs/jetty7-websockets-async "0.1.0"]
See the in-depth example for fancy core.match message dispatch and a core.async client in ClojureScript.
(require '[com.keminglabs.jetty7-websockets-async.core :refer [configurator]]
'[clojure.core.async :refer [chan go >! <!]]
'[ring.adapter.jetty :refer [run-jetty]])
(defn http-handler
[req]
{:response 200 :body "HTTP hello" :headers {}})
(def c (chan))
(def ws-configurator
(configurator c {:path "/"}))
(def server
(run-jetty http-handler {:configurator ws-configurator
:port 8090, :join? false}))
(go (loop []
(let [ws-req (<! c)]
(>! (:in ws-req) "Hello new websocket client!")
(recur))))
(require '[com.keminglabs.jetty7-websockets-async.core :refer [connect!]]
'[clojure.core.async :refer [chan go >! <!]])
(def c (chan))
(connect! c "ws://remote-server")
(go (loop []
(let [ws-req (<! c)]
(>! (:in ws-req) "Hello remote websocket server!")
(recur))))
Zach Allaun for suggesting that the websocket server and client code could be handled symmetrically.
Take a look at @ptaoussanis's Sente, which provides channels over WebSockets and Ajax on the http-kit server.