Skip to content

Instantly share code, notes, and snippets.

@shenfeng
Last active December 14, 2015 21:09
Show Gist options
  • Save shenfeng/5149007 to your computer and use it in GitHub Desktop.
Save shenfeng/5149007 to your computer and use it in GitHub Desktop.
(ns example
(:use [org.httpkit.server
compojure.core]))
(defn- handle-client-data [data]
(let [data (read-json data)]
;; routing can implented here. like socket.io's event routing
))
;;; when streaming/polling, client post data to server,
;;; mimic websocket's two way communication
(defn receive-data-handler [req]
(handle-client-data (slurp (:body req))) ; assume data is in the :body
{:status 200})
;;; use the unified with-channel API
(defn realtime-handler [req]
;; client use WebSocket if supported, long polling if no WebSocket support
(with-channel req channel
;; client/server close the channel(connection), do some clean up
;; eg: remove it from a channel-hub
(on-close channel (fn [status]
;; DO clean up.
))
;; setup handler for receive websocket message from client.
;; for streaming /post is used.
(on-receive channel (fn [data] ; data is raw string
(handle-client-data data)))
;; save channel somewhere (eg, a channel-hub) for later use,
;; waiting some event, then push sever data to client
;; sample channel-hub http://http-kit.org/channel.html#channel-group
;; if disingush here, there is no need to distingush them in on-interesting-server-events
(when-not (websocket? channel)
;; sent the header to client, tell client this a Chunked HTTP reponse
;; more json encoded data expected to come later,
(send! channel {:status 200
:headers {"Content-Type" "application/json"
"X-other-header" "value"}}
false)) ;do not close the channel
))
(on-interesting-server-events event
(let [channels (get-relevant-channels event)
data (compute-the-data-sent-to-client event)]
(doseq [ch channels]
(if (websocket? ch)
(send! ch (json-str data) false) ; do not close the channel, default is false
(send! ch {:status 200
;; tell client the body is json encoded
:headers {"Content-Type" "application/json"}
:body (json-str data)}
;; close the channel, allow javascript to comsume the data
;; the default value is true
true)))))
(defroutes app
(POST "/post" [] receive-data-handler)
(GET "/realtime" [] realtime-handler))
(run-server app {:port 9090})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment