Sending a binary string over websocket using jsoo


I am encoding data in the browser using CBOR on jsoo and want to send the rensult to my server. CBOR.encode returns a string and I want to send that over websocket but when I end up with garbled data, probably re-encoded because the input string is not UTF-8.

There is a function Websocket.send_buffer : Typed_array.arrayBuffer Js.t -> unit Js.meth but I don’t know how to go from my OCaml string to a value of that type. I will also need to do the opposite conversion but Typed_array.String.of_arrayBuffer : arrayBuffer Js.t -> string seems appropriate.

Any idea about the steps to follow?

I think I’ve managed to get closer: there seems to be no API for constructing a Typed_array directly from a string: even from JS it is necessary to provide a function that will translate from character to integer.

My current attempt is as follows:

      let constructor = in
      let typed_array = new%js constructor [|
        (object%js val length = String.length s end);
        Js.wrap_callback (fun _v k -> Char.code s.[k]);
      |] in

Unfortunately the two values I’m using in the array are not of the same type and I don’t know how to coerce the properly which is why I get the following:

Error: This expression has type
     ('a, 'b -> int -> int) Js_of_ocaml.Js.meth_callback
   but an expression was expected of type
     < length : int Js_of_ocaml.Js.readonly_prop > Js_of_ocaml.Js.t

How to provide a callback in the constructor of an object?

There are a couple issues above. First, I wanted to use JS’ Uint8Array.from() instead of new Uint8Array. Then, I mixed the PPX syntax with the manual one and tried to pass all of the arguments packed into an array. The proper way is:

      let constructor = in
      let typed_array = constructor##from
        (object%js val length = String.length s end)
        (Js.wrap_callback (fun _v k -> Char.code s.[k]))