Channel sockets. Otherwise known as The Shiz.
Protocol | client>server | client>server ?+ ack/reply | server>user push
[1] Emulate with cb-uuid wrapping. [2] Emulate with dummy-cb wrapping. [3] Emulate with long-polling.
Abbreviations:
Special messages:
Callback wrapping: [<clj> <?cb-uuid>] for [1],[2].
Callback replies: :chsk/closed, :chsk/timeout, :chsk/error.
Client-side events: [:chsk/handshake [<?uid> <?csrf-token> <?handshake-data>]], [:chsk/state <new-state>], [:chsk/recv <[buffered-evs]>] ; server>user push
Server-side events: [:chsk/ws-ping], [:chsk/bad-package <packed-str>], [:chsk/bad-event <chsk-event>], [:chsk/uidport-open], [:chsk/uidport-close].
Notable implementation details:
General-use notes:
Channel sockets. Otherwise known as The Shiz. Protocol | client>server | client>server ?+ ack/reply | server>user push * WebSockets: ✓ [1] ✓ * Ajax: [2] ✓ [3] [1] Emulate with cb-uuid wrapping. [2] Emulate with dummy-cb wrapping. [3] Emulate with long-polling. Abbreviations: * chsk - Channel socket. Sente's own pseudo "socket". * net-ch - Network channel. Underlying web server's channel. Must implement Sente's async net channel interface. * uid - User-id. An application-level user identifier used for async push. May have semantic meaning (e.g. username, email address), or not (e.g. client/random id) - app's discretion. * cb - Callback. * tout - Timeout. * ws - WebSocket/s. * pstr - Packed string. Arbitrary Clojure data serialized as a string (e.g. edn) for client<->server comms. Special messages: * Callback wrapping: [<clj> <?cb-uuid>] for [1],[2]. * Callback replies: :chsk/closed, :chsk/timeout, :chsk/error. * Client-side events: [:chsk/handshake [<?uid> <?csrf-token> <?handshake-data>]], [:chsk/state <new-state>], [:chsk/recv <[buffered-evs]>] ; server>user push * Server-side events: [:chsk/ws-ping], [:chsk/bad-package <packed-str>], [:chsk/bad-event <chsk-event>], [:chsk/uidport-open], [:chsk/uidport-close]. Notable implementation details: * core.async is used liberally where brute-force core.async allows for significant implementation simplifications. We lean on core.async's strong efficiency here. * For WebSocket fallback we use long-polling rather than HTTP 1.1 streaming (chunked transfer encoding). Http-kit _does_ support chunked transfer encoding but a small minority of browsers &/or proxies do not. Instead of implementing all 3 modes (WebSockets, streaming, long-polling) - it seemed reasonable to focus on the two extremes (performance + compatibility). In any case client support for WebSockets is growing rapidly so fallback modes will become increasingly irrelevant while the extra simplicity will continue to pay dividends. General-use notes: * Single HTTP req+session persists over entire chsk session but cannot modify sessions! Use standard a/sync HTTP Ring req/resp for logins, etc. * Easy to wrap standard HTTP Ring resps for transport over chsks. Prefer this approach to modifying handlers (better portability).
Alpha - subject to change. Simple+lightweight Ajax via Google Closure. Returns nil, or the xhr instance. Ref. https://developers.google.com/closure/library/docs/xhrio.
(ajax-call "/my-post-route" {:method :post :params {:username "Rich Hickey" :type "Awesome"} :headers {"Foo" "Bar"} :resp-type :text :timeout-ms 7000 :with-credentials? false ; Enable if using CORS (requires xhr v2+) } (fn async-callback [resp-map] (let [{:keys [success? ?status ?error ?content ?content-type]} resp-map] ;; ?status - 200, 404, ..., or nil on no response ;; ?error - e/o #{:xhr-pool-depleted :exception :http-error :abort ;; :timeout :no-content <http-error-status> nil} (js/alert (str "Ajax response: " resp-map)))))
Alpha - subject to change. Simple+lightweight Ajax via Google Closure. Returns nil, or the xhr instance. Ref. https://developers.google.com/closure/library/docs/xhrio. (ajax-call "/my-post-route" {:method :post :params {:username "Rich Hickey" :type "Awesome"} :headers {"Foo" "Bar"} :resp-type :text :timeout-ms 7000 :with-credentials? false ; Enable if using CORS (requires xhr v2+) } (fn async-callback [resp-map] (let [{:keys [success? ?status ?error ?content ?content-type]} resp-map] ;; ?status - 200, 404, ..., or nil on no response ;; ?error - e/o #{:xhr-pool-depleted :exception :http-error :abort ;; :timeout :no-content <http-error-status> nil} (js/alert (str "Ajax response: " resp-map)))))
(as-event x)
(assert-event x)
(cb-success? cb-reply-clj)
Note that cb reply need not be event
form!
Note that cb reply need _not_ be `event` form!
(chsk-send! chsk ev)
(chsk-send! chsk ev opts)
(chsk-send! chsk ev ?timeout-ms ?cb)
Sends [ev-id ev-?data :as event]
, returns true on apparent success.
Sends `[ev-id ev-?data :as event]`, returns true on apparent success.
(ƒ [path window-location websocket?]) -> server-side chsk route URL string.
make-channel-socket!
fn
(usu. "/chsk").Note that the same URL is used for: WebSockets, POSTs, GETs. Server-side routes should be configured accordingly.
(ƒ [path window-location websocket?]) -> server-side chsk route URL string. * path - As provided to client-side `make-channel-socket!` fn (usu. "/chsk"). * websocket? - True for WebSocket connections, false for Ajax (long-polling) connections. * window-location - Map with keys: :href ; "http://www.example.org:80/foo/bar?q=baz#bang" :protocol ; "http:" ; Note the : :hostname ; "example.org" :host ; "example.org:80" :pathname ; "/foo/bar" :search ; "?q=baz" :hash ; "#bang" Note that the *same* URL is used for: WebSockets, POSTs, GETs. Server-side routes should be configured accordingly.
(event-msg? x)
(chsk-send!* chsk ev opts)
Implementation detail.
Implementation detail.
(chsk-init! chsk)
Implementation detail.
Implementation detail.
(chsk-destroy! chsk)
Kills socket, stops auto-reconnects.
Kills socket, stops auto-reconnects.
(chsk-reconnect! chsk)
Drops connection, allows auto-reconnect. Useful for reauthenticating after login/logout.
Drops connection, allows auto-reconnect. Useful for reauthenticating after login/logout.
(make-channel-socket! path
&
&
[{:keys [type recv-buf-or-n ws-kalive-ms lp-timeout-ms
chsk-url-fn packer client-id ajax-opts]
:as opts
:or {type :auto
recv-buf-or-n (async/sliding-buffer 2048)
ws-kalive-ms 25000
lp-timeout-ms 25000
chsk-url-fn default-chsk-url-fn
packer :edn
client-id (or (:client-uuid opts) (enc/uuid-str))}}
_deprecated-more-opts])
Returns a map with keys:
:ch-recv ; core.async channel to receive event-msg
s (internal or from clients).
; May put!
(inject) arbitrary event
s to this channel.
:send-fn ; (fn [event & [?timeout-ms ?cb-fn]]) for client>server send.
:state ; Watchable, read-only (atom {:type _ :open? _ :uid _ :csrf-token _}).
:chsk ; IChSocket implementer. You can usu. ignore this.
Common options:
:type ; e/o #{:auto :ws :ajax}. You'll usually want the default (:auto)
:ws-kalive-ms ; Ping to keep a WebSocket conn alive if no activity w/in given
; number of milliseconds
:lp-kalive-ms ; Ping to keep a long-polling (Ajax) conn alive ''
:chsk-url-fn ; Please see default-chsk-url-fn
for details
:packer ; :edn (default), or an IPacker implementation (experimental)
:ajax-opts ; Base opts map provided to ajax-call
Returns a map with keys: :ch-recv ; core.async channel to receive `event-msg`s (internal or from clients). ; May `put!` (inject) arbitrary `event`s to this channel. :send-fn ; (fn [event & [?timeout-ms ?cb-fn]]) for client>server send. :state ; Watchable, read-only (atom {:type _ :open? _ :uid _ :csrf-token _}). :chsk ; IChSocket implementer. You can usu. ignore this. Common options: :type ; e/o #{:auto :ws :ajax}. You'll usually want the default (:auto) :ws-kalive-ms ; Ping to keep a WebSocket conn alive if no activity w/in given ; number of milliseconds :lp-kalive-ms ; Ping to keep a long-polling (Ajax) conn alive '' :chsk-url-fn ; Please see `default-chsk-url-fn` for details :packer ; :edn (default), or an IPacker implementation (experimental) :ajax-opts ; Base opts map provided to `ajax-call`
(set-exp-backoff-timeout! nullary-f & [nattempt])
(set-logging-level! level)
(start-chsk-router! ch-recv event-msg-handler & [{:as opts :keys [trace-evs?]}])
Creates a go-loop to call (event-msg-handler <event-msg>)
and returns a
(fn stop! [])
. Catches & logs errors. Advanced users may choose to instead
write their own loop against ch-recv
.
Creates a go-loop to call `(event-msg-handler <event-msg>)` and returns a `(fn stop! [])`. Catches & logs errors. Advanced users may choose to instead write their own loop against `ch-recv`.
(start-chsk-router-loop! event-handler ch-recv)
DEPRECATED: Please use start-chsk-router!
instead.
DEPRECATED: Please use `start-chsk-router!` instead.
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close