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 builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |