diff options
author | Clombrong <clombrong@egregore.fun> | 2025-04-22 14:35:23 +0200 |
---|---|---|
committer | Clombrong <cromblong@egregore.fun> | 2025-04-22 14:35:23 +0200 |
commit | 3c935560874956d1b2d92024d09544b749a707b2 (patch) | |
tree | e58bd4af3b45f626ae1b2024a9a25ebcc5d345a2 | |
parent | ca9611cef50cf81c47fcac3b1a8ef972b2d3dbf5 (diff) |
feat: new module flesh_websockets.
Create flesh_websockets module.
Add lwt_ws function.
-rw-r--r-- | dune-project | 15 | ||||
-rw-r--r-- | flesh_websockets.opam | 33 | ||||
-rw-r--r-- | lib/flesh/dune (renamed from lib/dune) | 1 | ||||
-rw-r--r-- | lib/flesh/flesh.ml (renamed from lib/flesh.ml) | 0 | ||||
-rw-r--r-- | lib/portal/dune | 6 | ||||
-rw-r--r-- | lib/portal/portal_ws.ml | 24 | ||||
-rw-r--r-- | test/js/dune | 5 | ||||
-rw-r--r-- | test/js/websockets_hello.ml | 20 |
8 files changed, 103 insertions, 1 deletions
diff --git a/dune-project b/dune-project index 7d0b0e4..a46653c 100644 --- a/dune-project +++ b/dune-project @@ -30,4 +30,19 @@ (tags (xmpp lwt))) +(package + (name flesh_websockets) + (synopsis "WebSockets Flesh portal") + (description "This library implements a Flesh portal for Websockets.") + (depends + ocaml + dune + js_of_ocaml + js_of_ocaml-ppx + (flesh + (and (= :version) + :with-test))) + (tags + (xmpp flesh websockets lwt))) + ; See the complete stanza docs at https://dune.readthedocs.io/en/stable/dune-files.html#dune-project diff --git a/flesh_websockets.opam b/flesh_websockets.opam new file mode 100644 index 0000000..553b2b3 --- /dev/null +++ b/flesh_websockets.opam @@ -0,0 +1,33 @@ +# This file is generated by dune, edit dune-project instead +opam-version: "2.0" +synopsis: "WebSockets Flesh portal" +description: "This library implements a Flesh portal for Websockets." +maintainer: ["Clombrong"] +authors: ["Clombrong"] +license: "LGPL-3.0-or-later" +tags: ["xmpp" "flesh" "websockets" "lwt"] +homepage: "https://forge.fsky.io/clombrong/flesh" +bug-reports: "https://forge.fsky.io/clombrong/flesh/issues" +depends: [ + "ocaml" + "dune" {>= "3.11"} + "js_of_ocaml" + "js_of_ocaml-ppx" + "flesh" {= version & with-test} + "odoc" {with-doc} +] +build: [ + ["dune" "subst"] {dev} + [ + "dune" + "build" + "-p" + name + "-j" + jobs + "@install" + "@runtest" {with-test} + "@doc" {with-doc} + ] +] +dev-repo: "git+https://forge.fsky.io/clombrong/flesh.git" diff --git a/lib/dune b/lib/flesh/dune index af1b3ad..d79e297 100644 --- a/lib/dune +++ b/lib/flesh/dune @@ -1,4 +1,3 @@ (library (public_name flesh) - (name flesh) (libraries lwt)) diff --git a/lib/flesh.ml b/lib/flesh/flesh.ml index 969d285..969d285 100644 --- a/lib/flesh.ml +++ b/lib/flesh/flesh.ml diff --git a/lib/portal/dune b/lib/portal/dune new file mode 100644 index 0000000..47b59ce --- /dev/null +++ b/lib/portal/dune @@ -0,0 +1,6 @@ +(library + (name portal_ws) + (modules portal_ws) + (public_name flesh_websockets) + (libraries lwt js_of_ocaml) + (preprocess (pps js_of_ocaml-ppx))) diff --git a/lib/portal/portal_ws.ml b/lib/portal/portal_ws.ml new file mode 100644 index 0000000..f2c0cf5 --- /dev/null +++ b/lib/portal/portal_ws.ml @@ -0,0 +1,24 @@ +open Lwt.Syntax + +open Js_of_ocaml +let jss = Js.string +let sjs = Js.to_string + +let lwt_ws (url : string) = + (** [lwt_ws url] returns a stream and a push function for the websocket at [url]. + Pushing [None] closes the websocket. + If the websocket is closed server-side, it's up to the caller's to close the push stream. *) + let open Lwt_stream in + let handle ws incoming () = + let+ _ = iter (fun msg -> ws##send (jss msg)) incoming + in (ws##close) + in let stream, message = create () (* websocket -> user *) + and incoming, push = create () (* user -> websocket *) + in let (ws : WebSockets.webSocket Js.t) = new%js WebSockets.webSocket (jss url) + in ws##.onmessage := + Dom.handler (fun x -> Some (sjs x##.data) |> message; Js._false); + ws##.onopen := + Dom.handler (fun _ -> Lwt.async @@ handle ws incoming; Js._false); + ws##.onclose := + Dom.handler (fun _ -> message None; Js._true); + stream, push diff --git a/test/js/dune b/test/js/dune new file mode 100644 index 0000000..d919a1e --- /dev/null +++ b/test/js/dune @@ -0,0 +1,5 @@ +(test + (name websockets_hello) + (libraries portal_ws lwt js_of_ocaml) + (modes js) + (preprocess (pps js_of_ocaml-ppx))) diff --git a/test/js/websockets_hello.ml b/test/js/websockets_hello.ml new file mode 100644 index 0000000..41487b7 --- /dev/null +++ b/test/js/websockets_hello.ml @@ -0,0 +1,20 @@ +open Lwt.Syntax + +let () = + (* Echo is a websocket that... echoes you stuff. *) + let stream, push = Portal_ws.lwt_ws "wss://echo.websocket.org" in + push (Some "great text"); + push (Some "other text"); + push (Some "yet another text"); + push (Some "BYE"); + Lwt.async @@ + fun () -> + let+ s = Lwt_stream.iter + (fun greetings -> + match greetings with + (* When the websocket sends "BYE", we close. *) + | "BYE" -> print_endline "CLOSING BYE"; push None + | hello -> print_endline ("> " ^ hello)) + stream + in s + |