在 Javascript 中通过 Web 套接字发送和接收二进制数据?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5766802/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Send and receive binary data over web sockets in Javascript?
提问by Chad Johnson
It is possible to send and receive binary data over web sockets in Javascript? Could I, for example, implement an SSH client using web sockets?
可以在 Javascript 中通过 Web 套接字发送和接收二进制数据吗?例如,我可以使用 Web 套接字实现 SSH 客户端吗?
回答by kanaka
The next draft (hybi-07) of the WebSockets specification is being implemented in most browsers and it will add built-in binary support to the protocol and API.
WebSockets 规范的下一个草案 ( hybi-07) 正在大多数浏览器中实现,它将为协议和 API 添加内置的二进制支持。
However, until then, WebSockets payload is encoded as UTF-8. In order to send binary data you must use some way of encoding the binary data as UTF-8.
但是,在此之前,WebSockets 负载被编码为 UTF-8。为了发送二进制数据,您必须使用某种方式将二进制数据编码为 UTF-8。
There are many options but here are two that I have used:
有很多选择,但这里有两个我用过:
UTF-8:
UTF-8:
You can actually encode a byte stream directly to UTF-8.
您实际上可以将字节流直接编码为 UTF-8。
The python to encode and decode would look something like this:
编码和解码的 python 看起来像这样:
from codecs import (utf_8_encode, utf_8_decode,
latin_1_encode, latin_1_decode)
utf_8_encode(unicode(buf, 'latin-1'))[0] # encode
latin_1_encode(utf_8_decode(utf8_buf)[0])[0] # decode
In Javascript:
在 JavaScript 中:
chr = data.charCodeAt(N) // to 'decode' at position N of the message
// Enocde array of bytes (0-255) to UTF-8
data = array.map(function (num) {
return String.fromCharCode(num); }).join('');
UTF-8 encode notes:
UTF-8 编码注释:
For binary data that is evenly distributed across value 0-255, then size of the payload is 50% larger than the raw binary data.
The Flash WebSockets emulator web-socket-jsmay have trouble with the encoding of 0 (zero).
对于在值 0-255 之间均匀分布的二进制数据,有效负载的大小比原始二进制数据大 50%。
Flash WebSockets 模拟器web-socket-js可能会遇到编码 0(零)的问题。
Base 64:
基数 64:
In python:
在蟒蛇中:
from base64 import b64encode, b64decode
data = b64encode(buf) # encode binary buffer to b64
buf = b64decode(data) # decode b64 to binary buffer
To encode and decode the messages on the Javascript side:
要在 Javascript 端对消息进行编码和解码:
data = window.btoa(msg) // Encode to base64
msg = window.atob(data) // Decode base64
msg.charCodeAt(N) // Read decode byte at N
Base 64 notes:
基 64 注释:
Evenly distributed binary data (0-255) will be 33% larger than the raw data.
There is less python side overhead to base64 encoding than there is to UTF-8 encoding. However, there is a bit more Javascript side overhead to decoding base64 (UTF-8 doesn't need decoding in Javascript since the browser has already converted the UTF-8 to the Javascript native UTF-16).
Update: This assumes the binary data is encoded to a UTF-8 string as shown above with character values that range from 0-255. Specifically, window.atob does not support character values above 255. See this mozilla bug. The same limitation applies to Chrome.
均匀分布的二进制数据 (0-255) 将比原始数据大 33%。
base64 编码的 python 端开销比 UTF-8 编码少。但是,解码 base64 需要更多的 Javascript 端开销(UTF-8 不需要在 Javascript 中解码,因为浏览器已经将 UTF-8 转换为 Javascript 原生 UTF-16)。
更新:这假设二进制数据被编码为 UTF-8 字符串,如上所示,字符值范围为 0-255。具体来说,window.atob 不支持大于 255 的字符值。请参阅此mozilla 错误。同样的限制也适用于 Chrome。
websockify:
websockify:
WebSockifyis a proxy/bridge that allows a WebSockets capable browser to communicate with any arbitrary binary service. It was created to allow noVNCto communicate with existing VNC servers. websockify uses base64 encode/decode of the binary data and also provides a websock.js
library for use in Javascript. The websock.js
has an API similar to regular WebSocket but it is handles binary data transparently and is designed to communicate with websockify. Disclaimer: I created websockify and noVNC.
WebSockify是一个代理/桥接器,它允许具有 WebSockets 功能的浏览器与任何任意二进制服务进行通信。它的创建是为了允许noVNC与现有的 VNC 服务器进行通信。websockify 使用二进制数据的 base64 编码/解码,还提供了一个websock.js
用于 Javascript的库。它websock.js
有一个类似于常规 WebSocket 的 API,但它透明地处理二进制数据,旨在与 websockify 通信。免责声明:我创建了 websockify 和 noVNC。
ssh client:
SSH客户端:
Technically you could implement a browser ssh client over WebSockets (and I've considered it), however, this will require doing SSH encryption and decryption in the browser which will be slow. Given that WebSockets has an encrypted WSS (TLS) mode, it probably makes more sense to do plain telnet over WebSocket WSS.
从技术上讲,您可以通过 WebSockets 实现浏览器 ssh 客户端(我已经考虑过),但是,这需要在浏览器中进行 SSH 加密和解密,这会很慢。鉴于 WebSockets 具有加密的 WSS (TLS) 模式,通过 WebSocket WSS 执行普通 telnet 可能更有意义。
In fact, websockify includes an example telnet client.
事实上,websockify 包含一个示例 telnet 客户端。
You would launch websockify on HOSTNAME like this (telnetd is from krb5-telnetd):
您可以像这样在 HOSTNAME 上启动 websockify(telnetd 来自 krb5-telnetd):
sudo ./websockify 2023 --web . --wrap-mode=respawn -- telnetd -debug 2023
Then navigate to http://HOSTNAME:2023/wstelnet.html?hostname=HOSTNAME&port=2023
然后导航到 http://HOSTNAME:2023/wstelnet.html?hostname=HOSTNAME&port=2023
See the websockify READMEfor more information. To use WSS encryption you will need to create an SSL key as described on the noVNC advanced usage wiki page
有关更多信息,请参阅websockify README。要使用 WSS 加密,您需要创建一个 SSL 密钥,如noVNC 高级用法维基页面上所述
回答by sra
One good and safe way to send and receive binary data is with base64 or base128 (where 128 has just 1/7 overhead instead of 1/3).
发送和接收二进制数据的一种好且安全的方法是使用 base64 或 base128(其中 128 的开销仅为 1/7 而不是 1/3)。
Yes an SSH Client is possible.
是的,SSH 客户端是可能的。
A proof for this is that there are already a lot of solutions out there that run in common browsers, but most of them still needs a custom server side implementation. You can look here for more information: http://en.wikipedia.org/wiki/Web-based_SSH
一个证明是,已经有很多解决方案可以在常见的浏览器中运行,但其中大多数仍然需要自定义服务器端实现。您可以在此处查看更多信息:http: //en.wikipedia.org/wiki/Web-based_SSH
回答by Etienne Prothon
Now you can send and receive binary data easily, this article explain lot of thinks : http://blog.mgechev.com/2015/02/06/parsing-binary-protocol-data-javascript-typedarrays-blobs/
现在你可以轻松地发送和接收二进制数据了,这篇文章解释了很多想法:http: //blog.mgechev.com/2015/02/06/parsing-binary-protocol-data-javascript-typedarrays-blobs/
Here is how I receive binary numpy array sent with python (my_nparray.tobytes()) in my browser:
这是我在浏览器中接收用 python (my_nparray.tobytes()) 发送的二进制 numpy 数组的方式:
ws = new WebSocket("ws://localhost:51234");
ws.binaryType = 'blob';
var buffer;
ws.onmessage = function (evt) {
var reader = new FileReader();
reader.readAsArrayBuffer(evt.data);
reader.addEventListener("loadend", function(e)
{
buffer = new Uint16Array(e.target.result); // arraybuffer object
});
};
You can convert typed array to javascript array with this:
您可以使用以下命令将类型化数组转换为 javascript 数组:
Array.prototype.slice.call(buffer.slice());
回答by Chad Johnson
Hmm, maybe WebSockets could somehow be combined with this: http://ie.microsoft.com/testdrive/HTML5/TypedArrays/
嗯,也许 WebSockets 可以以某种方式与此结合:http: //ie.microsoft.com/testdrive/HTML5/TypedArrays/