Skip to content

Commit

Permalink
Add docstrings to ring.websocket namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
weavejester committed Sep 10, 2023
1 parent 4ab0f5e commit 94d4795
Showing 1 changed file with 58 additions and 14 deletions.
72 changes: 58 additions & 14 deletions ring-core/src/ring/websocket.clj
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
(ns ring.websocket
"Protocols and utility functions for websocket support."
(:refer-clojure :exclude [send])
(:import [java.nio ByteBuffer]))

(defprotocol Listener
(on-open [listener socket])
(on-message [listener socket message])
(on-pong [listener socket data])
(on-error [listener socket throwable])
(on-close [listener socket code reason]))
"A protocol for handling websocket events. The second argument is
always an object that satisfies the Socket protocol."
(on-open [listener socket]
"Called when the websocket is opened.")
(on-message [listener socket message]
"Called when a message is received. The message may be a String or a
ByteBuffer.")
(on-pong [listener socket data]
"Called when a pong is received in response to an earlier ping. The client
may provide additional binary data, represented by the data ByteBuffer.")
(on-error [listener socket throwable]
"Called when an Throwable error is thrown.")
(on-close [listener socket code reason]
"Called when the websocket is closed, along with an integer code and a
plaintext string reason for being closed."))

(extend-protocol Listener
clojure.lang.IPersistentMap
Expand All @@ -23,19 +34,37 @@
(when-let [kv (find m :on-close)] ((val kv) socket code reason))))

(defprotocol Socket
(-send [socket message])
(-ping [socket data])
(-pong [socket data])
(-close [socket status reason]))
"A protocol for sending data via websocket."
(-send [socket message]
"Sends a String or ByteBuffer to the client via the websocket.")
(-ping [socket data]
"Sends a ping message to the client with a ByteBuffer of extra data.")
(-pong [socket data]
"Sends an unsolicited pong message to the client, with a ByteBuffer of extra
data.")
(-close [socket code reason]
"Closes the socket with an integer status code, and a String reason."))

(defprotocol AsyncSocket
(-send-async [socket message succeed fail]))
"A protocol for sending data asynchronously via websocket. Intended for use
with the Socket protocol."
(-send-async [socket message succeed fail]
"Sends a String or ByteBuffer to the client via the websocket. If it
succeeds, the 'succeed' callback function is called with zero arguments. If
it fails, the 'fail' callback function is called with the exception that was
thrown."))

(defprotocol TextData
(->string [data]))
"A protocol for converting text data into a String."
(->string [data]
"Convert some data into a String, ready to be sent as a websocket text
message."))

(defprotocol BinaryData
(->byte-buffer [data]))
"A protocol for converting binary data into a java.nio.ByteBuffer object."
(->byte-buffer [data]
"Convert some binary data into a java.nio.ByteBuffer, ready to be sent as
a websocket binary message."))

(extend-protocol TextData
String
Expand All @@ -55,33 +84,48 @@
{:message message}))))

(defn send
"Sends text or binary data via a websocket, either synchronously or
asynchronously with callback functions. A convenient wrapper for the -send and
-send-async protocol methods."
([socket message]
(-send socket (encode-message message)))
([socket message succeed fail]
(-send-async socket (encode-message message) succeed fail)))

(defn ping
"Sends a ping message via a websocket, with an optional byte array or
ByteBuffer that may contain custom session data. A convenient wrapper for the
-ping protocol method."
([socket]
(-ping socket (ByteBuffer/allocate 0)))
([socket data]
(-ping socket (->byte-buffer data))))

(defn pong
"Sends an unsolicited pong message via a websocket, with an optional byte
array or ByteBuffer that may contain custom session data. A convenient wrapper
for the -pong protocol method."
([socket]
(-pong socket (ByteBuffer/allocate 0)))
([socket data]
(-pong socket (->byte-buffer data))))

(defn close
"Closes the websocket, with an optional custom integer status code and reason
string."
([socket]
(-close socket 1000 "Normal Closure"))
([socket code reason]
(-close socket code reason)))

(defn websocket-request? [request]
(defn websocket-request?
"Returns true if the request map expects a websocket response."
[request]
(let [headers (:headers request)]
(and (.equalsIgnoreCase "upgrade" (get headers "connection"))
(.equalsIgnoreCase "websocket" (get headers "upgrade")))))

(defn websocket-response? [response]
(defn websocket-response?
"Returns true if the response contains a websocket listener."
[response]
(contains? response ::listener))

0 comments on commit 94d4795

Please sign in to comment.