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> nil[4] <?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 :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:
[4] Used to be a csrf-token. Was removed in v1.14 for security reasons.
A nil
remains for semi-backwards-compatibility with pre-v1.14 clients.
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> nil[4] <?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 :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). [4] Used to be a csrf-token. Was removed in v1.14 for security reasons. A `nil` remains for semi-backwards-compatibility with pre-v1.14 clients.
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.
Sente server adapter for Aleph (https://github.com/ztellman/aleph).
Sente server adapter for Aleph (https://github.com/ztellman/aleph).
Sente server adapter for Node.js with Dog Fort (https://github.com/whamtet/dogfort).
Sente server adapter for Node.js with Dog Fort (https://github.com/whamtet/dogfort).
Sente server adapter for Node.js with Express (http://expressjs.com/).
This adapter works differently that the others as Sente is expecting Ring requests but Express uses http.IncomingMessage. While most of this adapter could be used for similar implementations there will be assumptions here that the following express middleware (or equivalents) are in place:
See the example project at https://goo.gl/lnkiqS for an implementation (it's a bit different than something built on Ring).
Sente server adapter for Node.js with Express (http://expressjs.com/). This adapter works differently that the others as Sente is expecting Ring requests but Express uses http.IncomingMessage. While most of this adapter could be used for similar implementations there will be assumptions here that the following express middleware (or equivalents) are in place: - cookie-parser - body-parser - csurf - express-session - express-ws See the example project at https://goo.gl/lnkiqS for an implementation (it's a bit different than something built on Ring).
Sente server adapter for Node.js using the ws
and http
libraries.
Ref. https://github.com/websockets/ws,
https://nodejs.org/api/http.html,
https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/,
https://github.com/theasp/sente-nodejs-example.
Sente server adapter for Node.js using the `ws` and `http` libraries. Ref. https://github.com/websockets/ws, https://nodejs.org/api/http.html, https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/, https://github.com/theasp/sente-nodejs-example.
Sente server adapter for http-kit (http://www.http-kit.org/).
Sente server adapter for http-kit (http://www.http-kit.org/).
Sente server adapter for Immutant v2+ (http://immutant.org/).
Sente server adapter for Immutant v2+ (http://immutant.org/).
Sente adapter for ring-jetty9-adapter, (https://github.com/sunng87/ring-jetty9-adapter).
Note that ring-jetty9-adapter defines WebSocket routes/handlers separately from regular Ring routes/handlers [1,2].
This can make it tricky to set up stateful middleware correctly (for example as you may want to do for CSRF protection).
See [3] for a full example.
[1] https://github.com/sunng87/ring-jetty9-adapter/blob/master/examples/rj9a/websocket.clj [2] https://github.com/sunng87/ring-jetty9-adapter/issues/41#issuecomment-630206233 [3] https://gist.github.com/wavejumper/40c4cbb21d67e4415e20685710b68ea0
Sente adapter for ring-jetty9-adapter, (https://github.com/sunng87/ring-jetty9-adapter). Note that ring-jetty9-adapter defines WebSocket routes/handlers separately from regular Ring routes/handlers [1,2]. This can make it tricky to set up stateful middleware correctly (for example as you may want to do for CSRF protection). See [3] for a full example. [1] https://github.com/sunng87/ring-jetty9-adapter/blob/master/examples/rj9a/websocket.clj [2] https://github.com/sunng87/ring-jetty9-adapter/issues/41#issuecomment-630206233 [3] https://gist.github.com/wavejumper/40c4cbb21d67e4415e20685710b68ea0
Sente server adapter for Node.js with the Macchiato Framework (https://macchiato-framework.github.io/).
Sente server adapter for Node.js with the Macchiato Framework (https://macchiato-framework.github.io/).
Sente server adapter for Nginx-Clojure v0.4.2+ (http://nginx-clojure.github.io/).
Sente server adapter for Nginx-Clojure v0.4.2+ (http://nginx-clojure.github.io/).
Sente server adapter for ring-undertow-adapter.
Sente server adapter for ring-undertow-adapter.
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close