Converting audio file into bytes and send over web socket

Hi, I’ve a use case where I need to load an audio file and send it to web socket.

let audioData = open(“…/foo.wav”,“b”);

This is not recognized by the Web Socket server. Any inputs on how we can send the data as arraybuffer?

Hi @vinzy,
Can you elaborate on what you mean by

Preferably with some more code and what exactly k6 and possibly the web server returns as errors/warnings.

Thanks @mstoykov for the reply.
I read the audio file (.wav) as binary data and am sending this data in the send method of the websocket. I’m seeing encoding exception at the server end. Not sure if I’m missing something.

let audioData = open(“…/foo.wav”,“b”);
> let url = “wss://”+tenant.serverhost+“/voice/stream/”

    var params = {"headers": {"Origin": "*"}};

    var response = ws.connect(url, params, function (socket) {

        socket.on('open', function open() {
                  console.log('Session Open on '+tenant.serverhost);

            console.log('Message 1: -> ' +tenant.serverhost+  ' sending the audio file ' );
                       socket.send(audioData);
        });

This is probably because currently k6 only sends ws messages as text.

If you can I would advice you to download the code, change TextMessage to BinaryMessage and test it. After which to report it as an issue in order for us to add … possibly another method for binary send (?).

If you can’t I can’t I can probably do it for you and build you a binary for your OS to test, although this might take some time :slight_smile: .I can’t know what exactly the server doesn’t like … it might not be this at all :frowning:

But we do probably need a way for people to send binary messages over websocket, so if you don’t I will open an issue at a later point .

@mstoykov, thanks for the confirmation.

I use docker image to run my tests. It would be really helpful, If you can let me know the steps on how to do the changes.

I will report the issue for binary support in web socket.

Regards,
Vinay

you will need to:

  1. need to have golang installed. If you don’t probably some of the following steps will be much more harder for you :frowning:
  2. go get github.com/loadimpact/k6
  3. cd $GOPATH/src/github.com/loadimpact/k6
  4. edit the file I’ve linked above changing TextMessage to BinaryMessage in the place linked
  5. go install .
  6. k6 run path/to/your/script.js

All of the above steps are for … non windows systems ;). Haven’t used WIndows in years as a user but I hear you now have a nice terminal and shell so they might work in the majority of cases :slight_smile:

Thanks @mstoykov. I will give a try.

I see there is a comment that goja doesn’t support typed arrays. Will this not be an issue if we add the Binary Message. Also, can we write a new function ?

func (s *Socket) SendBinary(message string) {
// NOTE: No binary message support for the time being since goja doesn’t
// support typed arrays.
rt := common.GetRuntime(s.ctx)

writeData := byte(message)
if err := s.conn.WriteMessage(websocket.BinaryMessage, writeData); err != nil {
s.handleEvent(“error”, rt.ToValue(err))
}

s.msgSentTimestamps = append(s.msgSentTimestamps, time.Now())
}

There is a very good chance it won’t work exactly because of the missing of a good way to handle binary data.

But by what I can see the BinaryMessage is also a requirement.

You can also change message string in the definition to writeData []byte and remove the line writeData := []byte(message) if it doesn’t work after just change BinaryMessage.

And yeah we are probably going to add another function or add a parameter as in the case of open, but we first much know if it will help you or anyone else :slight_smile: .

Thanks @mstoykov. Works like a charm. Thanks much.

Here is the code I’ve added.

func (s *Socket) SendBinary(writeData byte) {
// NOTE: No binary message support for the time being since goja doesn’t
// support typed arrays.
rt := common.GetRuntime(s.ctx)

//writeData := byte(message)
if err := s.conn.WriteMessage(websocket.BinaryMessage, writeData); err != nil {
s.handleEvent(“error”, rt.ToValue(err))
}

s.msgSentTimestamps = append(s.msgSentTimestamps, time.Now())
}

1 Like

Glad that it worked.

Do you want to make a PR :wink: There will be the need for a small test but still, though.

Sure @mstoykov. I will create a PR and add the test. Where can I add the test?

Also, I want to include an external sdk into k6? Could you please suggest how can we go about it? The external sdk is required for http-signing .

for the PR:

  1. You can copy paste this and change it to send some binary data (preferably really not something that can be represented as text)
    2.You should probably wait for Correctly handle server-initiated WebSocket close by imiric · Pull Request #1186 · grafana/k6 · GitHub to be merged as it’s touching somethings there and this might turn to be a problem. After it’s merged (probably in the next hour) you can rebase your changes and make a PR
  2. Thanks :confetti_ball: !!!

About the sdk: I don’t understand the question. What kind of sdk, for what and in what language?
If it’s :

  1. golang … k6 doesn’t have such functionality … you will need to patch it in yourself, and it’s fairly unlikely that we will add it to the official k6 :frowning:
  2. js:
    2.1.you might just import it but if it’s using crypto something … it’s not going to work as k6 doesn’t implement any … standard(ish) crypto library we have our own … which is currently in feature freeze until we decide … well what standard(ish) crypto library we are going to implement.
    2.2. You can take a look at how it’s proposed to use browserify for … additional compatibility with node.
    2.3. And finally I have a small repo that showcases how you can use webpack (and npm and friends) to import npm modules and they directly to be … webpacked (?)
  3. not any of the above … well, you more or less can’t :slight_smile:

p.s. this might be better for another thread instead of … hijacking this one :wink:

Thanks @mstoykov. Will make the PR after the merge is done.

I will create another thread for the SDK :smiley:

2 Likes

@vinzy do you have repo that i can have a look on how you implement binary file into k6 websocket?

Nice work!
But why can’t you use the command WebSocet.send() instead of (audioData)?
It works well with this site (worktime.com) .