How to read BLOB data from a WebSocket which is not an image
Asked Answered
G

4

18

I created a WebSocket connection to my webserver to receive some data. However, when I log the event that I receive in the onmessage function, then I cannot see the real content of the data.

When I copy the network connection that my Chrome browser v32 opens as a curl command and run it on my OS console, then everything works fine. So I think that somehow my WebSocket setup must be wrong. The event.data object is an instance of Blob.

Here is my code (actually CoffeeScript, but easy to understand):

socket = new WebSocket "wss://myserverurl/some-endpoint"

socket.onopen = (event) ->
    console.log 'Connection opened (WebSocket)'

socket.onclose = (event) ->
    console.log 'Connection closed (WebSocket)'
    code = event.code
    reason = event.reason
    wasClean = event.wasClean

socket.onmessage = (event) ->
    console.log JSON.stringify event

The event that I get:

{
    "ports": [],
    "data": {
        "type": "",
        "size": 594
    },
    ...
    "cancelBubble": false,
    "returnValue": true,
    "srcElement": {
        "binaryType": "blob",
        "extensions": "",
        "protocol": "",
        "onerror": null,
        "bufferedAmount": 0,
        "readyState": 1
    },
    "defaultPrevented": false,
    "timeStamp": 1390578698613,
    "cancelable": false,
    "bubbles": false,
    "eventPhase": 2,
    "currentTarget": {
        "binaryType": "blob",
        "extensions": "",
        "protocol": "",
        "onerror": null,
        "bufferedAmount": 0,
        "readyState": 1
    },
    "target": {
        "binaryType": "blob",
        "extensions": "",
        "protocol": "",
        "onerror": null,
        "bufferedAmount": 0,
        "readyState": 1
    },
    "type": "message"
}
Gifu answered 24/1, 2014 at 17:1 Comment(0)
G
19

Ok, I found the solution! I have to read the data that comes as a Blob with a FileReader:

socket = new WebSocket 'wss://myserverurl/some-endpoint'
socket.binaryType = 'blob'

socket.onopen = (event) ->
    console.log 'Connection opened (WebSocket)'

socket.onclose = (event) ->
    console.log 'Connection closed (WebSocket)'
    code = event.code
    reason = event.reason
    wasClean = event.wasClean

socket.onmessage = (event) ->
    if event.data instanceof Blob
        reader = new FileReader()
        reader.onload = ->
            console.log reader.result
        reader.readAsText event.data

Alternatively, in ES2015:

// Create socket
socket = new WebSocket("wss://example.org/ws");
socket.binaryType = "blob";

// Log socket opening and closing
socket.addEventListener("open", event => {
    console.log("Websocket connection opened");
});
socket.addEventListener("close", event => {
    console.log("Websocket connection closed");
});

// Handle the message
socket.addEventListener("message", event => {
    if (event.data instanceof Blob) {
        reader = new FileReader();

        reader.onload = () => {
            console.log("Result: " + reader.result);
        };

        reader.readAsText(event.data);
    } else {
        console.log("Result: " + event.data);
    }
});
Gifu answered 24/1, 2014 at 17:28 Comment(1)
Why do I receive something like �� �����.(�ǣ��.8��Z@M`�D�� when I try to get reader.result?Bainter
I
11

You can set tye binaryType of the WebSocket in JavaScript like:

var socket = new WebSocket(url);
socket.binaryType = "arraybuffer";

Or respectively in CoffeeScript

socket = new WebSocket url
socket.binaryType = "arraybuffer"

And you will get ArrayBuffers instead of Blobs. Convert them to Uint8Array by new Uint8Array(event.data);

Ianteen answered 17/2, 2021 at 0:23 Comment(0)
S
3

you can also use Blob.text().

socket.addEventListener("message", event => {
    // event.data is Blob
    event.data.text().then(txt=>console.log(txt))   
});
Shadbush answered 7/2, 2022 at 14:34 Comment(0)
P
-1

Basically the best answer I can tell that it's preferred thing to only send string messages in websocket.

So the solution is when sending messages I will highly recommend you to use:

JSON.stringify(data)

So, what it does is converting the arrays or objects or any type of data into string

So when you get the data or the message you should converting them back into what status it was on that would be so easy by doing this:

JSON.parse(msg)
Pettifogger answered 27/8, 2021 at 19:53 Comment(1)
Tried it, didn't work. Corrupted 37 into [50, 55] somehow?Disoblige

© 2022 - 2024 — McMap. All rights reserved.