Reputation: 357
I am trying to build a loop with Lwt that will push a frame to a Websocket, wait for the response, print it to the screen, wait 60 seconds and then repeat the process again. I have been able to get something that compiles but I do not have it 100% right yet. The first time through the loop everything works fine, then every time after that I receive the error message "Invalid UTF8 data". I must have something wrong in my Lwt loop or in my understanding of Websocket protocols. My code:
#require "websocket";;
#require "lwt";;
#require "lwt.syntax";;
open Lwt
(* Set up the websocket uri address *)
let ws_addr = Uri.of_string "websocket_address"
(* Set up the websocket connection *)
let ws_conn = Websocket.open_connection ws_addr
(* Set up a frame *)
let ws_frame = Websocket.Frame.of_string "json_string_to_server"
(* push function *)
let push frame () =
ws_conn
>>= fun (_, ws_pushfun) ->
ws_pushfun (Some frame);
Lwt.return ()
(* get stream element and print to screen *)
let get_element () =
let print_reply (x : Websocket.Frame.t) =
let s = Websocket.Frame.content x in
Lwt_io.print s; Lwt_io.flush Lwt_io.stdout;
in
ws_conn
>>= fun(ws_stream, _) ->
Lwt_stream.next ws_stream
>>= print_reply
let rec main () =
Lwt_unix.sleep 60.0
>>= (push ws_frame)
>>= get_element
>>= main
Lwt_main.run(main ())
Upvotes: 3
Views: 337
Reputation: 35280
I'm not sure what particularly incorrect with your code. It even doesn't compiles on my system. It looks like you were experimenting with it in a top-level and created some strange context. I've rewritten your code in a somewhat more cleaner way. First of all I pass a connection to the function, so that it is more cleaner, what your functions do. Also it is not a good idea to wait for the same thread again and again. This is not how things are done is Lwt.
open Lwt
(* Set up the websocket uri address *)
let ws_addr = Uri.of_string "websocket_address"
(* Set up a frame *)
let ws_frame = Websocket.Frame.of_string "json_string_to_server"
(* push function *)
let push (_,push) frame =
push (Some frame);
return_unit
(* get stream element and print to screen *)
let get_element (stream,_) =
let print_reply (x : Websocket.Frame.t) =
let s = Websocket.Frame.content x in
Lwt_io.printlf "%s%!" s in
Lwt_stream.next stream
>>= print_reply
let rec main conn : unit t =
Lwt_unix.sleep 60.0
>>= fun () -> push conn ws_frame
>>= fun () -> get_element conn
>>= fun () -> main conn
let () = Lwt_main.run (
Websocket.open_connection ws_addr >>= main)
Upvotes: 1