Sending binary data via websocket using cowboy and MessagePack

I am trying to send a MessagePack encoded message from Cowboy to a browser via WebSocket, and the received data is always empty or invalid. I can send binary data from JS to my cowboy handler, but not vice versa. I am using Cowboy 1.0.4 with official msgpack-erlang . I also use msgpack-lite for my built-in javascript browser.

Examples:

websocket_handler :

 websocket_handle({text, <<"return encoded">>}, Req, State) -> %% sends encoded message to client. Client is unable to decode and fails {reply, {binary, msgpack:pack(<<"message">>)}, Req, State}; websocket_handle({binary, Encoded}, Req, State) -> %% Works as expected lager:info("Received encoded message: ~p", [msgpack:unpack(Encoded)]), {ok, Req, State}; 

JS:

 var host = "ws://" + window.location.host + "/websocket"; window.socket = new WebSocket(host); socket.binaryType = 'arraybuffer'; socket.onmessage = function(event) { var message = msgpack.decode(event.data); console.log(message); }; 

The browser returns an error inside msgpack.min.js:

 Error: Invalid type: undefined ...ion n(t){var r=i(t),e=f[r];if(!e)throw new Error("Invalid type: "+(r?"0x"+r.toSt... 

If I try to output raw event.data to the console, this is what I get:

  ArrayBuffer {} 

For some reason, it seems like it's empty. I am new to erlang and msgpack and I don't know what is going wrong. Thank you for your help!

+5
source share
3 answers

Found the cause of my problem. The way I tried to decode the message on the client was wrong:

 socket.onmessage = function(event) { var message = msgpack.decode(event.data); console.log(message); }; 

The right way:

 socket.onmessage = function(event) { var raw_binary_data = new Uint8Array(event.data); var message = msgpack.decode(raw_binary_data); console.log(message); }; 
+3
source

msgpack-lite doesn't seem to support binary type. Try packing your data as a string.

 {binary, msgpack:pack("message", [{enable_str, true}])} 
0
source

Using Uint8Array is a valid solution for a client side problem. On the server for batch strings, use:

 msgpack:pack(<<"message">>,[{pack_str,from_binary}]) 

Source: Article

0
source

Source: https://habr.com/ru/post/1245547/


All Articles