package ws

  1. Overview
  2. Docs
Generic websocket implementation for OCaml

Install

Dune Dependency

Authors

Maintainers

Sources

0.1.tar.gz
md5=c1f9283e0afa9ea2f30d3bf64eb338fa
sha512=729267d7227084cc3214d36b4cb4d61f150586e61349ceba3bce3dd5cfff2f990ecbd153c07a7fa031f0a3cdca6121a2cb5b1e9be143a04c93dec257f5b78229

Description

README

WS

Websocket Implementation for OCaml

(Server only, client coming soon)

The following is an example for getting set websockets set up with cohttp + Lwt. Note that this example requires cohttp >= v2.0 which is unreleased (as of writing), but you can pull and pin the master branch with:

$ git clone git@github.com:mirage/ocaml-cohttp.git
$ opam pin ocaml-cohttp

Also the example depends on interface-prime-lwt:

$ opam install interface-prime-lwt

The example is also contained in example/example_server.ml.

Example:

open Lwt
open Cohttp
open Cohttp_lwt_unix

module Websocket = Ws.Make(Interface'_lwt.Io)

let respond ?headers status message =
  let len = String.length message |> Int64.of_int in
  let res_f = Response.make ~encoding:(Transfer.Fixed len) ~status in
  let res = match headers with
      | Some headers -> res_f ~headers:(headers |> Header.of_list) ()
      | None -> res_f () in
    (res, fun _ oc -> Lwt_io.write oc message) |> return

let ws_handler send =
  Some "Welcome to my websocket!" |> send
  >>= fun _ ->
  return (function
    | Some m -> Lwt_io.printf "Received message: %s\n" m
      >>= fun _ -> Some (Printf.sprintf "Thanks, I got [%s]" m) |> send
    | None -> Lwt_io.printf "Connection closed\n")

let server =
  let callback _conn req _body =
    let meth = req |> Request.meth in
    let headers = req |> Request.headers |> Header.to_list in
    match meth with
      | `GET ->
          (if Ws.is_websocket_upgrade headers then
            match Websocket.upgrade headers with
              | Error e_headers ->
                let res = Response.make ~encoding:(Transfer.Unknown) ~status:`Bad_request ~headers:(e_headers |> Header.of_list) () in
                (res, fun _ _ -> return_unit) |> return
              | Ok ok_headers ->
                let res = Response.make ~encoding:(Transfer.Unknown) ~status:`Switching_protocols ~headers:(ok_headers |> Header.of_list) () in
                (res, fun ic oc -> Websocket.handle_server ws_handler ic oc) |> return
          else
            respond `Bad_request "")
      | _ ->
        respond `Method_not_allowed "Only websocket protocol supported!"
  in
    Server.create ~mode:(`TCP (`Port 8000)) (Server.make_expert ~callback ())

let () = ignore (Lwt_main.run server)

Dependencies (8)

  1. interface-prime >= "0.1"
  2. sha >= "1.12"
  3. ppx_deriving >= "4.2.1"
  4. containers >= "2.4"
  5. bitstring >= "3.1.0" & < "4.0.0"
  6. base64 >= "2.3.0" & < "3.0.0"
  7. dune >= "1.6.2"
  8. ocaml >= "4.05"

Dev Dependencies

None

Used by

None

Conflicts

None

OCaml

Innovation. Community. Security.