如何通过Websocket将arraybuffer作为二进制发送?

Posted

技术标签:

【中文标题】如何通过Websocket将arraybuffer作为二进制发送?【英文标题】:How send arraybuffer as binary via Websocket? 【发布时间】:2012-03-21 17:33:57 【问题描述】:

我正在与 Mozilla Europe 合作开展一个项目。在这个项目中,我使用 Worlize(服务器端)和 Mozilla(客户端)的 websocket,Node.js 来尝试将文件从客户端上传到服务器。 我目前的目标是将文件的arraybuffer 发送到服务器。创建数组缓冲区并发送它就可以了。 但是我的服务器告诉我 arraybuffer 是一个 utf8 消息而不是二进制消息。

我是不是误会了什么?如果没有,我该如何纠正?

客户端:

    reader = new FileReader();
    reader.readAsArrayBuffer(file);
    reader.onload = function(e) 
        connection.send(e.target.result); 
    ;

服务器端:

ws.on('message', function(message,flags) 
if (!flags.binary) 
    //some code

else 
    console.log('It\'s a binary');

我也尝试使用Blob,结果相同。二进制部分是不可见的。

【问题讨论】:

这是一个问答网站,“分叉和参与”不会在这里发生(参见***.com/faq)。另外,请不要要求人们深入研究您的代码 - 包括解释您正在做什么所必需的最少代码。 我意识到这是前段时间有人问过的,所以我只是想添加 Firefox 11 及更高版本支持二进制 ArrayBuffer 和 Blob。 【参考方案1】:

Gecko11.0 ArrayBuffer 发送和接收对binary data 的支持已经实现。

connection = new WebSocket( 'ws://localhost:1740' );
connection.binaryType = "arraybuffer";
connection.onopen = onopen;
connection.onmessage = onmessage;
connection.onclose = onclose;
connection.onerror = onerror;

发送Binary data:

function sendphoto() 
    imagedata = context.getImageData( 0, 0, imagewidth, imageheight );
    var canvaspixelarray = imagedata.data;
    var canvaspixellen = canvaspixelarray.length;
    var bytearray = new Uint8Array( canvaspixellen );
    for ( var i = 0; i < canvaspixellen; ++i ) 
        bytearray[i] = canvaspixelarray[i];
    
    connection.send( bytearray.buffer );
    context.fillStyle = '#ffffff';
    context.fillRect( 0, 0, imagewidth, imageheight );

接收Binary Data:

if ( event.data instanceof ArrayBuffer ) 
    var bytearray = new Uint8Array( event.data );
    var tempcanvas = document.createElement( 'canvas' );
    tempcanvas.height = imageheight;
    tempcanvas.width = imagewidth;
    var tempcontext = tempcanvas.getContext( '2d' );
    var imgdata = tempcontext.getImageData( 0, 0, imagewidth, imageheight );
    var imgdatalen = imgdata.data.length;
    for ( var i = 8; i < imgdatalen; i++ ) 
        imgdata.data[i] = bytearray[i];
    
    tempcontext.putImageData( imgdata, 0, 0 );
    var img = document.createElement( 'img' );
    img.height = imageheight;
    img.width = imagewidth;
    img.src = tempcanvas.toDataURL();
    chatdiv.appendChild( img );
    chatdiv.innerhtml = chatdiv.innerHTML + "<br />";

【讨论】:

你的意思是Gecko11.0 但是我怎样才能将苍蝇的名字连同数据一起发送呢?如果我把它放在 JSON 中,JSON.stringify 不适用于数组缓冲区... @bluejayke 将字符串数据转换为类型化数组并合并缓冲区。还要添加一个字节长度标志来指示文件名缓冲区的长度,以便接收者知道要读取和发送组合缓冲区的字节数,例如:文件名长度|文件名|原始数据的其余部分。【参考方案2】:
Note: Prior to version 11, Firefox only supported sending data as a string.

来源:https://developer.mozilla.org/en/WebSockets/Writing_WebSocket_client_applications

【讨论】:

以上是关于如何通过Websocket将arraybuffer作为二进制发送?的主要内容,如果未能解决你的问题,请参考以下文章

如何将带有 ArrayBuffer 的 JSON 对象发送到 websocket?

如何通过WebSocket的二进制发送arraybuffer

小程序websocket推送消息Uint8Array/ArrayBuffer

微信小程序如何将base64转成file格式

如何在 JS 中从 ArrayBuffer 写入文件

在网页上用websocket播放RTSP实时流 性能优化 进阶方案