WebSocket frame codec (RFC 6455)
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

OCaml 93.2%
Dune 1.9%
Other 4.8%
17 1 0

Clone this repository

https://tangled.org/gazagnaire.org/ocaml-websocket https://tangled.org/did:plc:jhift2vwcxhou52p3sewcrpx/ocaml-websocket
git@git.recoil.org:gazagnaire.org/ocaml-websocket git@git.recoil.org:did:plc:jhift2vwcxhou52p3sewcrpx/ocaml-websocket

For self-hosted knots, clone URLs may differ based on your setup.

Download tar.gz
README.md

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