Some tools I use often, w/o any external deps.
Some tools I use often, w/o any external deps.
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).
Experimental - subject to change! Public interfaces / extension points.
Experimental - subject to change! Public interfaces / extension points.
Experimental - subject to change! Optional Transit-format[1] IPacker implementation for use with Sente. [1] https://github.com/cognitect/transit-format.
Experimental - subject to change! Optional Transit-format[1] IPacker implementation for use with Sente. [1] https://github.com/cognitect/transit-format.
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close