Liking cljdoc? Tell your friends :D

taoensso.sente

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).
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).
raw docstring

ajax-callcljs

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)))))
raw docstring

as-eventcljs

(as-event x)

assert-eventcljs

(assert-event x)

cb-success?cljs

(cb-success? cb-reply-clj)

Note that cb reply need not be event form!

Note that cb reply need _not_ be `event` form!
raw docstring

ChAjaxSocketcljs


chsk-send!cljs

(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.
raw docstring

ChWebSocketcljs


default-chsk-url-fncljs

(ƒ [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.

(ƒ [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.
raw docstring

event-msg?cljs

(event-msg? x)

event?cljs

(event? x)

Valid [ev-id ?ev-data] form?

Valid [ev-id ?ev-data] form?
raw docstring

IChSocketcljsprotocol

chsk-send!*cljs

(chsk-send!* chsk ev opts)

Implementation detail.

Implementation detail.

chsk-init!cljs

(chsk-init! chsk)

Implementation detail.

Implementation detail.

chsk-destroy!cljs

(chsk-destroy! chsk)

Kills socket, stops auto-reconnects.

Kills socket, stops auto-reconnects.

chsk-reconnect!cljs

(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!cljs

(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-msgs (internal or from clients). ; May put! (inject) arbitrary events 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`
raw docstring

set-exp-backoff-timeout!cljs

(set-exp-backoff-timeout! nullary-f & [nattempt])

set-logging-level!cljs

(set-logging-level! level)

start-chsk-router!cljs

(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`.
raw docstring

start-chsk-router-loop!cljs

(start-chsk-router-loop! event-handler ch-recv)

DEPRECATED: Please use start-chsk-router! instead.

DEPRECATED: Please use `start-chsk-router!` instead.
raw docstring

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close