Flush data added to websocket

Viewed 114

I'm writing a speed test, but i'm having trouble on the client side for uploading.

I have a the following setup, which basically continues to write data into the socket while a condition is true, and then closes the socket:

    var ws = await createWebSocket(sb.serverAddress, sb.authToken);

    while (condition) {
      var bytes = generateRandomBytes(_BUFFER_SIZE_BYTES);
      ws.add(bytes);
      print('added');
      var megabits = (bytes.length * 8) / 1000000;
      channel.sink.add(megabits);
    }
    await ws.close();

My problem is that I can't work out how to wait for the bytes to be accepted by the underlying buffer. Even if I set _BUFFER_SIZE_BYTES to an huge size it still loops at break neck speed printing out added, where I really want to wait until all the bytes are accepted by the send buffer (having been accepted by the server) before adding a new list of bytes.

With an http post request you can do: await postReq.flush();, but I don't see any such method for web sockets.

1 Answers

Ok so I think I have a reasonable solution to this problem.

Client side has to wait for a response from the server before sending more bytes:

    var bytes = generateRandomBytes(_CHUNK_SIZE_BYTES);

    ws.listen((data) async {
        ws.add(bytes);
        var megabits = (bytes.length * 8) / 1000000;
        channel.sink.add(megabits);
      }
    });

Server (Go) sends a message to the client signalling that it can send a chunk, and then reads the entire response from the client, before signalling to the client that it is ready to accept another one:

    for start := time.Now(); time.Since(start) < time.Second*maxDuration; {
        err := conn.WriteMessage(websocket.TextMessage, []byte("next"))
        if err != nil {
            break
        }

        // will get an error if try writing to closed socket
        _, bytes, err := conn.ReadMessage()
        if err != nil {
            fmt.Println(err)
            break
        }
        fmt.Println(len(bytes))
    }

I think this solution is ok. I've set the chunk size to 10Mb which seems to work ok. Let me know if anyone has a better idea.

Related