WebSockets
The :std/net/websocket package provides functionality for writing
websocket clients and servers.
To use bindings from this module
(import :std/net/websocket)
WebSocket interface
(interface (WebSocket Socket)
(send (msg :~ valid-message?))
(recv) ; -> message
(protocol)
(max-frame-size))
(defstruct message (data type partial?) final: #t
constructor: :init!)
(def (valid-message? msg)
(using (msg : message)
(if (memq msg.type '(text close))
(check-argument (string? msg.data) "string" msg.data)
(check-argument (u8vector? msg.data) "u8vector" msg.data))))
(defmethod {:init! message}
(lambda (self data type (partial? #f))
(using (self :- message)
(set! self.data data)
(set! self.type type)
(set! self.partial? partial?))))
The WebSocket interface provides the abstractions for sending and receiving messages.
Messages are instances of message, which encapsulates the data together with its type
and a partial frame indicator.
The following bindings providing the necessary functionality for working with websockets.
message
(defstruct message (data type partial?))
Instances of message are the unit of IO for websockets. The struct
has the following fields:
datais the payload of the message.- If the message type is
'textor'close, then it must be a string - Otherwise, it is a u8vector.
- If the message type is
typeis the type of the message, a symbol. It must be one of'binaryfor a binary message.'textfor a textual message.'pingfor a ping message; the programmer should reply with'pongmessage.'pongfor a pong message, sent as a reply to a previous'ping.'closefor gracefully closing the socket; the program should close the websocket.
partial?is a boolean, with true value indicating that this is a partial message.
websocket-connect
(websocket-connect url
protocol: (proto #f)
redirect: (redirect #f)
headers: (headers #f)
cookies: (cookies #f)
params: (params #f)
auth: (auth #f)
ssl-context: (ssl-context (default-client-ssl-context))
timeout: (timeo #f)
max-frame-size: (max-frame-size default-max-frame-size))
-> WebSocket
This is the client side of websockets; it connects to the url and
returns an instance of WebSocket.
The redirect, headers, cookies, params, auth, ssl-context
and timeout parameters are passed to the http request when
establishing a connection; see HTTP requests for more
information.
The protocol parameter is an optional comma separated list of protocols,
for websocket protocol negotiation.
The max-frame-size parameter specifies the maximum accepted size for a
frame; it defaults to 1MB.
websocket-request-handler
(websocket-request-handler continue select-protocol
max-frame-size: (max-frame-size default-max-frame-size))
-> WebSocket
continue := lambda (WebSocket)
select-protocol := lambda ([string ...]) -> string or #f
This is the server side of websockets; it creates a request handler for the http server, that accepts and upgrades websocket requests.
The procedure requires two arguments:
continueis a procedure that takes aWebSocketinstance to handle the interaction. It is invoked by the http handler after the connection has been successfully upgraded.select-protocolis a procedure that takes a list of websocket protocols (strings) and selects one of them or returns #f if it doesn't support any of client specified protocols. Note that if the client does not specify a protocol, theselect-protocolwill not be invoked.
The max-frame-size parameter specifies the maximum accepted size for a
frame; it defaults to 1MB.
WebSocket-send
(WebSocket-send sock message)
sock := WebSocket
Sends a message, which must not exceed the maximum frame size in binary size.
WebSocket-send-all
(WebSocket-send-all sock message)
sock := WebSocket
Sends a message even if it exceeds the maximum frame size, by fragmenting it into multiple partial messages.
WebSocket-recv
(WebSocket-recv sock) -> message
sock := WebSocket
Receives the next message, which must not exceed the maximum frame size in binary size.
WebSocket-recv-all
(WebSocket-recv-all sock maximum-message-size) -> message
sock := WebSocket
Receives a stream of partial messages (frames) and assembles them into
a single aggregate message. If the incoming stream of partial
messages exceeds the maximum-message-size in total, an error is
raised.
WebSocket-protocol
(WebSocket-protocol sock) -> maybe string
sock := WebSocket
This is the protocol negotiated for this socket; it can be #f if the
client didn't ask for any particular protocol.
WebSocket-max-frame-size
(WebSocket-max-frame-size sock) -> nonnegative-fixnum
sock := WebSocket
The maximum frame size supported by this websocket. The implementation
of send will raise an error if the programmer attempts to send a
message (frame) larger than this number. Similarly, the implementation
of recv will send an error if a frame header is received with size
larger than this number.