-
Notifications
You must be signed in to change notification settings - Fork 10
/
websocket_server.clj
53 lines (46 loc) · 1.64 KB
/
websocket_server.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
(ns kaocha.cljs.websocket-server
(:require [cognitect.transit :as transit]
[org.httpkit.server :as ws])
(:import [java.io ByteArrayInputStream ByteArrayOutputStream]
java.util.concurrent.BlockingQueue))
(try
(require 'matcher-combinators.model)
(catch Exception e))
(def handlers
(reduce
(fn [handlers sym]
(if-let [var (resolve (symbol (str "matcher-combinators.model/map->" sym)))]
(assoc handlers
(str "matcher-combinators.model." sym)
(transit/read-handler @var))
handlers))
{"var" (transit/read-handler identity)}
'[Mismatch
Missing
Unexpected
InvalidMatcherType
InvalidMatcherContext
FailedPredicate
TypeMismatch]))
(defn to-transit [value]
(let [out (ByteArrayOutputStream. 4096)
writer (transit/writer out :json)]
(transit/write writer value)
(.toString out)))
(defn from-transit [^String transit]
(let [in (ByteArrayInputStream. (.getBytes transit))
reader (transit/reader in :json {:handlers handlers})]
(transit/read reader)))
(defn ws-handler [^BlockingQueue queue]
(fn [req]
(ws/with-channel req con
(.put queue {:type ::connect :client con})
(ws/on-receive con (fn [msg]
(let [msg (from-transit msg)]
(.add queue {:type ::message :client con :message msg}))))
(ws/on-close con (fn [status]
(.add queue {:type ::disconnect :client con}))))))
(defn send! [client message]
(ws/send! client (to-transit message) false))
(defn start! [queue]
(ws/run-server (ws-handler queue) {:port 0 :join? false}))