-
-
Save tobias/d1270180f4857826af1e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defprotocol Channel | |
"Streaming channel interface" | |
(open? [ch] "Is the channel open?") | |
(close [ch] | |
"Gracefully close the channel. | |
This will trigger the :on-close callback if one is registered. with | |
[[as-channel]].") | |
(handshake [ch] | |
"Returns a [[WebsocketHandshake]] for `ch` if `ch` is a WebSocket channel.") | |
(send! [ch message & options] | |
"Send a message to the channel. | |
`message` can either be a String or byte[]. | |
The following options are supported [default]: | |
* :close? - if `true`, the channel will be closed when the send completes. | |
Setting this to `true` on the first send to an HTTP stream channel | |
will cause it to behave like a standard HTTP response, and *not* chunk | |
the response. [false] | |
* :on-complete - `(fn [] ...)` - called when the send has completed [nil] | |
* :on-error - `(fn [throwable] ...)` - called when an error occurs on the | |
send. For HTTP stream channels, this includes when the client closes the | |
connection before the server does (which will also trigger a call to | |
the :on-close handler of [[as-channel]]) [nil] | |
Sending is asynchronous for WebSockets, but blocking for | |
HTTP channels. TODO: this may change to all-async | |
Returns nil if the channel is closed when the send is initiated, true | |
otherwise.")) | |
(defn as-channel | |
"Converts the current ring `request` in to an asynchronous channel. | |
The type of channel created depends on the request - if the request | |
is a Websocket upgrade request, a Websocket channel will be created. | |
Otherwise, an HTTP stream channel is created. You interact with both | |
channel types through the [[Channel]] protocol, and through the | |
given `callbacks`. | |
The callbacks common to both channel types are: | |
* :on-open - `(fn [ch] ...)` - called when the channel is | |
available for sending. Will only be invoked once. | |
* :on-close - `(fn [ch {:keys [code reason]}] ...)` - | |
called for *any* close, including a call to [[close]], but will | |
only be invoked once. `ch` will already be closed by the time | |
this is invoked. | |
`code` and `reason` will be the numeric closure code and text reason, | |
respectively, if the channel is a WebSocket. Both will be nil for | |
HTTP streams. | |
If the channel is a Websocket, the following callbacks are also used: | |
* :on-message - `(fn [ch message] ...)` - Called for each message | |
from the client. `message` will be a `String` or `byte[]` | |
* :on-error - `(fn [ch throwable] ...)` - Called for any error | |
that occurs outside of a [[send!]] call. To handle `send!` errors, | |
provide an error callback to it. | |
TODO: discuss: sessions, headers, ws vs http diffs (utf8, no headers) | |
provide usage example | |
Returns a ring response map, at least the :body of which *must* be | |
returned in the response map from the calling ring handler." | |
[request & callbacks] | |
...) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment