websocket#
RFC 6455 WebSocket frame codec for OCaml.
websocket encodes and decodes RFC 6455 frames: text,
binary, ping, pong, close, with masking and fragmentation. It does
not perform the HTTP upgrade handshake — drive that with an HTTP
client or server (e.g. requests) and hand the negotiated
byte stream here.
Installation#
Install with opam:
$ opam install nox-websocket
If opam cannot find the package, it may not yet be released in the
public opam-repository. Add the overlay repository, then install
it:
$ opam repo add samoht https://tangled.org/gazagnaire.org/opam-overlay.git
$ opam update
$ opam install nox-websocket
Usage#
Encode a text frame (client frames are masked by default, as required by the RFC):
# let frame = Websocket.text "hello" in
let bytes = Websocket.encode frame in
String.length bytes
- : int = 11
Decode a frame from a buffer. The decoder returns the frame and any trailing bytes, or signals that more input is needed:
# let bytes = Websocket.encode ~mask:false (Websocket.text "hello") in
match Websocket.decode bytes with
| Ok ({ opcode; payload; fin }, rest) ->
Fmt.str "opcode=%a payload=%S fin=%b rest=%d"
Websocket.pp_opcode opcode payload fin (String.length rest)
| Error `Need_more -> "need more"
| Error (`Invalid m) -> "invalid: " ^ m
- : string = "opcode=text payload=\"hello\" fin=true rest=0"
Need_more is the normal case while streaming: keep reading from
the socket and re-attempting the decode until a frame lands:
# let full = Websocket.encode ~mask:false (Websocket.binary "\x01\x02\x03") in
let partial = String.sub full 0 (String.length full - 1) in
Websocket.decode partial
- : (Websocket.t * string, [ `Invalid of string | `Need_more ]) result =
Error `Need_more
Build the common control frames directly:
# let p = Websocket.ping "keepalive"
and c = Websocket.close ~code:1000 ~reason:"normal" () in
(p.opcode, c.opcode)
- : Websocket.opcode * Websocket.opcode = (Websocket.Ping, Websocket.Close)
Licence#
ISC