piaf icon indicating copy to clipboard operation
piaf copied to clipboard

websocket lags behind on many incoming messages

Open copy opened this issue 7 months ago • 0 comments

To reproduce, a slight modification of examples/eio/echo_server_upgrade.ml:

open Eio.Std
open Piaf

let connection_handler { Server.request; _ } =
  Response.Upgrade.websocket request ~f:(fun wsd ->
      let frames = Ws.Descriptor.messages wsd in
      Stream.iter frames ~f:(fun (opcode, iovec_frame) ->
          match opcode with
          | `Text ->
            let message = Bigstringaf.substring iovec_frame.Faraday.buffer ~off:iovec_frame.off ~len:iovec_frame.len in
            Eio.traceln "Received message: '%s'" message;
            Ws.Descriptor.send_string wsd message;
          | _ ->
            ())
    )
  |> Result.get_ok

let setup_log ?style_renderer level =
  Fmt_tty.setup_std_outputs ?style_renderer ();
  Logs.set_level (Some level);
  Logs.set_reporter (Logs_fmt.reporter ());
  ()

let () =
  setup_log Logs.Debug;
  let port = ref 8080 in
  Arg.parse
    [ "-p", Arg.Set_int port, " Listening port number (8080 by default)" ]
    ignore
    "Echoes websocket messages. Runs forever.";
  Eio_main.run (fun env ->
    Switch.run (fun sw ->
      let config =
        Server.Config.create (`Tcp (Eio.Net.Ipaddr.V4.loopback, !port))
      in
      let server = Server.create ~config connection_handler in
      let _command = Server.Command.start ~sw env server in
      ()
      (* Eio.Time.sleep (Eio.Stdenv.clock env) 5.; *)
      (* Server.Command.shutdown command *)))

With a javascript (I used nodejs) client that sends 100 messages at once (you may need to change the number) and then one message per second:

const socket = new WebSocket("ws://127.0.0.1:8080");

socket.onopen = function() {
    console.log("Connected to WebSocket server");
    let i = 0;
    for (; i < 100; i++) {
        socket.send(i.toString());
        console.log("send", i);
    }
    setInterval(() => {
        socket.send(i.toString());
        console.log("send", i);
        i++;
    }, 1000);
};
socket.onmessage = function(data) { console.log("receive", data.data); };
socket.onclose = function() { console.log("close"); };
socket.onerror = function(error) { console.error("error", error); };

The server usually lags behind after ~80 messages, and then processes one old message on every incoming new message, so the client prints:

…
receive 81
receive 82
receive 83
receive 84
receive 85
receive 86
receive 87
receive 88
send 100
receive 89
send 101
receive 90
send 102
receive 91
send 103
receive 92
send 104
receive 93
send 105
receive 94
send 106
receive 95
send 107
receive 96
^C

And the server:

…
+Received message: '81'
+Received message: '82'
+Received message: '83'
+Received message: '84'
+Received message: '85'
+Received message: '86'
+Received message: '87'
+Received message: '88'
+Received message: '89'
+Received message: '90'
+Received message: '91'
+Received message: '92'
+Received message: '93'
+Received message: '94'
+Received message: '95'
+Received message: '96'
echo_server_upgrade.exe: [INFO] Websocket connection EOF

Tested with current master (6c310f3), eio 1.2, OCaml 5.2 on Linux.

copy avatar May 28 '25 11:05 copy