使用Cowboy和MessagePack发送二进制数据到Websocket

7
我想在Cowboy中使用MessagePack编码将消息发送到浏览器,但接收到的数据始终为空或无效。我能够从JS向我的cowboy处理程序发送二进制数据,但反之则不行。 我正在使用Cowboy 1.0.4和官方msgpack-erlang应用程序。 我还为我的浏览器端JavaScript使用msgpack-lite。 示例: 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);
};

浏览器在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...

如果我尝试将原始的事件数据输出到控制台,我得到的是这样的内容:
 ArrayBuffer {}

由于某些原因似乎是空的。我对erlangmsgpack都很陌生,不知道出了什么问题。谢谢你的帮助!

3个回答

6

我找到了问题的原因。我之前在客户端尝试解码信息的方式是错误的:

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

正确的方式:

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

0

看起来 msgpack-lite 不支持二进制类型。尝试将您的数据打包为字符串。

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

谢谢,但是这并没有帮助。我认为主要原因是空的ArrayBuffer值。配置有问题,但我不知道是什么 :( - Constantine EmeraldMaster
@ConstantineEmeraldMaster:你尝试过并验证了WebSocket通信是否按照你的期望工作吗?我怀疑你在JS端根本没有收到任何东西。先发送未打包的字符串。 - Hynek -Pichi- Vychodil
通信可以使用文本模式双向进行,也可以在二进制模式下单向进行(从客户端到服务器)。JS客户端无法接收来自服务器的二进制消息。 - Constantine EmeraldMaster
@ConstantineEmeraldMaster:event.data里面有内容吗? - Hynek -Pichi- Vychodil
event.data 返回一个空的 ArrayBuffer {} - Constantine EmeraldMaster
@ConstantineEmeraldMaster:所以问题出在WebSocket而不是msgpack上。检查一下是否有二进制输出从msgpack:pack(<<"message">>)。它应该是<<196,7,109,101,115,115,97,103,101>>。然后可能是在{binary, _}或者socket.binaryType = 'arraybuffer'中出了问题。我不知道。你应该能够以这种方式发送普通的二进制数据。 - Hynek -Pichi- Vychodil

0

使用Uint8Array是客户端问题的有效解决方案。在服务器上打包字符串,请使用:

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

来源:文章


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接