Channel sockets for Clojure/Script.
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> <first-handshake?>]] [:chsk/state [<old-state-map> <new-state-map>]] [:chsk/recv <ev-as-pushed-from-server>] ; Server>user push [:chsk/ws-ping]
Server-side events: [:chsk/bad-package <packed-str>] [:chsk/bad-event <event>] [:chsk/uidport-open <uid>] [:chsk/uidport-close <uid>] [:chsk/ws-ping]
Channel socket state map: :type - e/o #{:auto :ws :ajax} :open? - Truthy iff chsk appears to be open (connected) now :ever-opened? - Truthy iff chsk handshake has ever completed successfully :first-open? - Truthy iff chsk just completed first successful handshake :uid - User id provided by server on handshake, or nil :csrf-token - CSRF token provided by server on handshake, or nil :handshake-data - Arb user data provided by server on handshake :last-ws-error - ?{:udt _ :ev <WebSocket-on-error-event>} :last-ws-close - ?{:udt _ :ev <WebSocket-on-close-event> :clean? _ :code _ :reason _} :last-close - ?{:udt _ :reason _}, with reason e/o #{nil :requested-disconnect :requested-reconnect :downgrading-ws-to-ajax :unexpected} :udt-next-reconnect - Approximate udt of next scheduled auto-reconnect attempt
Notable implementation details:
General-use notes:
Channel sockets for Clojure/Script.
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")
* server-ch - Underlying web server's async channel that implement
Sente's server channel interface
* sch - server-ch alias
* uid - User-id. An application-level user identifier used for async
push. May have semantic meaning (e.g. username, email address),
may 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
* udt - Unix timestamp (datetime long)
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> <first-handshake?>]]
[:chsk/state [<old-state-map> <new-state-map>]]
[:chsk/recv <ev-as-pushed-from-server>] ; Server>user push
[:chsk/ws-ping]
* Server-side events:
[:chsk/bad-package <packed-str>]
[:chsk/bad-event <event>]
[:chsk/uidport-open <uid>]
[:chsk/uidport-close <uid>]
[:chsk/ws-ping]
Channel socket state map:
:type - e/o #{:auto :ws :ajax}
:open? - Truthy iff chsk appears to be open (connected) now
:ever-opened? - Truthy iff chsk handshake has ever completed successfully
:first-open? - Truthy iff chsk just completed first successful handshake
:uid - User id provided by server on handshake, or nil
:csrf-token - CSRF token provided by server on handshake, or nil
:handshake-data - Arb user data provided by server on handshake
:last-ws-error - ?{:udt _ :ev <WebSocket-on-error-event>}
:last-ws-close - ?{:udt _ :ev <WebSocket-on-close-event>
:clean? _ :code _ :reason _}
:last-close - ?{:udt _ :reason _}, with reason e/o
#{nil :requested-disconnect :requested-reconnect
:downgrading-ws-to-ajax :unexpected}
:udt-next-reconnect - Approximate udt of next scheduled auto-reconnect attempt
Notable implementation details:
* core.async is used liberally where brute-force core.async allows for
significant implementation simplifications. We lean on core.async's
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).Sente client adapter for Aleph (https://github.com/ztellman/aleph).
Sente client adapter for Aleph (https://github.com/ztellman/aleph).
Alpha, subject to change. Public interfaces / extension points.
Alpha, subject to change. Public interfaces / extension points.
Alpha - subject to change! Optional Transit-format[1] IPacker implementation for use with Sente. [1] https://github.com/cognitect/transit-format.
Alpha - subject to change! Optional Transit-format[1] IPacker implementation for use with Sente. [1] https://github.com/cognitect/transit-format.
No vars found in this namespace.
Sente server adapter for Aleph (https://github.com/ztellman/aleph).
Sente server adapter for Aleph (https://github.com/ztellman/aleph).
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 |