This library provides WebSocket APIs defined by RFC 6455.
Following is a simple example to use user level APIs.
(import (rnrs) (rfc websocket))
;; Creates an WebSocket object
(define websocket (make-websocket "wss://echo.websocket.org"))
;; Sets text message event handler
(websocket-on-text-message websocket
(lambda (ws text) (display text) (newline)))
;; Opens the WebSocket
(websocket-open websocket)
;; Sends a message to endpoint
(websocket-send websocket "Hello")
;; Closes the WebSocket
(websocket-close websocket)
Creates an WebSocket object which communicate to given uri.
The URI reprented by uri must be a valid WebSocket URI. If it's
not a valid URI, then &websocket-engine
or its sub condition
shall be raised.
The keyword argument protocols are a list of sub protocols of the
creating WebSocket. If this is set, then handshake will send it with
Sec-WebSocket-Protocol
header or equivalent.
The keyword argument extensions are a list of extensions of the
creating WebSocket. If this is set, then handshake will send it with
Sec-WebSocket-Extensions
header or equivalent.
The keyword argument engine is a type of handshake engine and
must be a symbol. This determines which handshake protocol it should
use. The default value is http
which uses HTTP/1.1.
Returns #t if given obj is an WebSocket object otherwise #f.
Operating handshake on given WebSocket object websocket if it's not opened, yet. And returns websocket.
If handshake failed, then &websocket-engine
or its sub condition
shall be raised.
After successfull call of this procedure, the websocket has a message dispatcher thread.
Closes the given websocket if it's open and returns the
websocket. This procedure also finishes the underlying thread
created by websocket-open
.
The keyword argument status is specified, it must be a non negative integer which has less then or equal to 16 bits length, then the procedure sends it as a connection close code.
The keyword argument message is specified, must be a string, then the procedure sends it as a connection close message. This is sent only if the status is specified otherwise ignored.
The keyword argument timeout is used as a timeout period for waiting
underlying dispatcher thread. If the thread didn't finish in the specified
period, then it'd be terminated and &websocket-close-timeout
is
raised.
If the underlying thread raised an &uncaught-exception
, then the
procedure raises its reason.
Sends given data to the websocket and returns websocket. This procedure runs in atomic so the data is sent in one fragmentation sequence.
The optional arguments are passed to underlying data transport procedures.
If the data is a string, then websocket-send-text
is used.
If the data is a bytevector, then websocket-send-binary
is used.
If the data is not one of the aboves, then &assertion
is raised.
Send ping control frame whose data is data to _websocket_and returns websocket.
The procedure waits until the endpoint returns pong control frame. If the
pong frame doesn't contain the same data in its payload, then
&websocket-pong
is raised.
The optional argument timeout specifies how long the procedure waits the pong response.
The optional argument timeout-value is an alternative value when the endpoint didn't return pong in time.
CAUTION: this procedure depends on the endpoint's behaviour.
The user level APIs are event driven like JavaScript's WebSocket API. Whenever an event is occured, then the configured event handler is invoked.
There are 2 types of error handler invocations. One is calling active
procedures such as websocket-send
. The other one is passive situation
such as receiving frame from endpoint. The first case, all active procedures
would catch &websocket
and its sub conditions. If the condition is
&websocket-engine
or its sub condition, then the condition is
re-raised. Other &websocket
conditions are not re-raised by the
APIs. Other conditions are simply re-raised without invcating event handler.
On the second case, it's mostly the same, but when
&websocket-closed
is raised, then event handler won't be invoked.
Sets event-handler for receiving text message and binary message to websocket, respectively.
The event-handler must be a procedure which accepts 2 arguments, WebSocket object and response data, string or bytevector.
If the event-handler raises an error, and it's not
a &websocket
, then the dispatcher thread opened by
websocket-open
stops running.
The procedure returns websocket.
Sets event-handler for open and close event to websocket, respectively.
The event-handler must be a procedure which accepts 1 argument, WebSocket object.
The procedure returns websocket.
Sets event-handler for error situation to websocket.
The event-handler must be a procedure which accepts 2 arguments, WebSocket object and a captured error.
If the event-handler raises an error, then it would be propagated caller of the user level APIs.
The procedure returns websocket.
The low level APIs can be used when users want to implement WebSocket process in programatic way. The user level APIs are implemented on this APIs.
Creates WebSocket connection object. uri and engine are the same as make-websocket.
Returns #t if given obj is WebSocket connection object otherwise #f.
Processes handshake on given connection. All the optional arguments are passed to underlying handshake engine.
Closes given connection. This procedure simply closes socket connection.
Returns #t if the connection is not connected otherwise #f.
Returns a shared queue which stores pong data from the endpoint of the connection.
Sends text or binary frame of data to given connection.
If the first procedure is called, then data must be a string.
If the second procedure is called, then data must be a bytevector.
The optional argument start specifies from which point of data to send.
The optional argument split is specified, it must be an non negative integer or procedure which accepts 2 arguments, data and start, then the data is sent fragmented.
Sends close control frame to given connection.
If the optional argument data is specified, it must be a properly coded connection close status, the it's sent as a payload of close frame.
If the optional argument wait? is true value, then the procedure waits until the endpoint sends close frame back.
If wait? is #f, then it is users responsibility to receive the response close frame and closes the connection.
Sends ping and pong frame to given connection respectively.
The optional argument data is sent as its payload.
NB: the payload must be less than 125 bytes.
Receives a data frame and return 2 values, opcode and payload.
If the frame is text, then returning value is a string. Otherwise returning value is a bytevector.
If the keyword argument push-pong? is true value, then
payload of pong control frame will be pushed in to the pong-queue
of the connection.
This procedure doesn't return ping and pong control frame.
Receives a data fragments until its end and return the result of the last call of proc.
The proc must accept 3 values, finished?, opcode and data.
This procedure is useful to receive a huge frame without concising.
The websocket-receive
is implemented on top of this procedure
like this:
(define (websocket-receive conn :key (push-pong? #f))
(define (convert opcode data)
(if (eqv? opcode +websocket-text-frame+)
(values opcode (utf8->string data))
(values opcode data)))
(let-values (((out extract) (open-bytevector-output-port)))
(websocket-receive-fragments conn
(lambda (fin? opcode data)
(put-bytevector out data)
(if fin? (convert opcode (extract)) (values opcode #f)))
:push-pong? push-pong?)))
status must be an non negative integer whose bit length must be less than or equal to 16 bits.
If optional argument message is specified, then it must be a string.
Composes a payload of close frame.
data must be a payload of close frame.
Returns 2 values, status and mesasge of the close frame payload.
WebSocket frame type constants. It represents text frame and binary frame, respectively.
WebSocket control frame type constants. It represents cloe frame, ping frame, and pong frame, respectively.
&websocket
is a base condition of the WebSocket library's condition.
The hierarchy is the following:
+ &error
+ &websocket
+ &websocket-engine
+ &websocket-engine-not-found
- engine
- reason
+ &websocket-engine-scheme
- scheme
+ &websocket-engine-connection
- host
- port
+ &websocket-closed
- status
- message
+ &websocket-pong
- pong-data
+ &websocket-close-timeout
The condition types are not exported by the library.