This project use the cljs lib ftravers/transit-websocket-client. It should be paired with ftravers/websocket-server
Add to project:
(ns ...
(:require [reframe-websocket.core :as reframe-websocket]))
This will create an event handler called :get
and a subscription
handler called :set
to be used like:
(reframe/dispatch-sync [:set [:some :path] "abc123"])
;; sets the path [:some :path] to value "abc123" in the app-db
@(reframe/subscribe [:get [:some :path]])
;; => "abc123"
(def my-aws (reframe-websocket/async-websocket "ws://localhost:7890"))
;; Send a message, specify where to store the response
(let [my-message {:my-message "blah" :some-param 12345}
my-store-location [:store :path]]
(reframe-websocket/send-msg my-message my-store-location my-aws))
;; retrieve the response
@(reframe/subscribe [:get [:store :path]])
(def my-aws (reframe-websocket/async-websocket "ws://localhost:7890"))
(defn ws-send-msg
[path-msg path-resp db]
(reframe-websocket/send-msg (get-in db path-msg) path-resp aws))
(def path-msg [:send-msg :msg])
(def path-resp [:send-msg :resp])
(def ws-send-msg-interceptor (rf/after (partial ws-send-msg path-msg path-resp)))
(rf/reg-event-db
::send-msg
[ws-send-msg-interceptor]
(fn-traced [db [_ msg]]
(assoc-in db path-msg msg)))
If you use ftravers/websocket-server as the server websocket, you should start your server with these input and output functions:
(start-ws-server
port
:on-receive
(fn [[store-path data]]
[store-path (handle data)])
:in-fn
(fn [s]
(let [[_ rf-msg] (json/read-str s)]
(read-string rf-msg)))
:out-fn
(fn [msg]
(json/write-str
["~#'" (str msg)])))
You can then send message from the backend with send-all. They will be stored in [:store :path] of your app-db and trigger the subscribes.
; String
(send-all! port [[:store :path] "Message from backend"])])
; EDN
(send-all! port [[:store :path] {:map "Hello" :text "EDN from backend"}])])
; You can subscribe to them as for responses to client requests:
@(reframe/subscribe [:get [:store :path]])
If you need to do something else when receiving a message (more than just set the value into app-db at store-path),
you can add a key to reframe-websocket/async-websocket
. This event key will be dispatched each time a message is received
with the store-path and msg.
; Register a custom event to handle received messages from websocket
(rf/reg-event-db
:set-ws
(fn [db [_ store-path data]]
(if (= store-path [:ws :hello])
(assoc db :hello (hello data))))
; Give the key of this event to
(def my-aws (reframe-websocket/async-websocket "ws://localhost:7890" :set-ws))
In this case, pay attention to a few things:
:set
is still executed and data
will be set in app-db store-path
:set-ws
event will be executed both for messages coming from the server as for the responses to messages from clientCan you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close