可以通过Javascript中的Web套接字发送和接收二进制数据吗?例如,我可以使用Web套接字实现SSH客户端吗?
答案 0 :(得分:45)
WebSockets规范的下一个草案(hybi-07)正在大多数浏览器中实现,它将为协议和API添加内置的二进制支持。
但是,在此之前,WebSockets有效负载编码为UTF-8。为了发送二进制数据,您必须使用某种方式将二进制数据编码为UTF-8。
有很多选择,但这里有两个选项:
<强> UTF-8 强>:
您实际上可以将字节流直接编码为UTF-8。
编码和解码的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
在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编码说明:
对于均值分布在0-255之间的二进制数据,有效载荷的大小比原始二进制数据大50%。
Flash WebSockets模拟器web-socket-js可能遇到编码为0(零)的问题。
基础64 :
在python中:
from base64 import b64encode, b64decode
data = b64encode(buf) # encode binary buffer to b64
buf = b64decode(data) # decode b64 to binary buffer
在Javascript端编码和解码消息:
data = window.btoa(msg) // Encode to base64
msg = window.atob(data) // Decode base64
msg.charCodeAt(N) // Read decode byte at N
基础64注释:
均匀分布的二进制数据(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 bug。同样的限制适用于Chrome。
<强> websockify 强>:
WebSockify是一个代理/网桥,允许支持WebSockets的浏览器与任意二进制服务进行通信。创建它是为了允许noVNC与现有VNC服务器通信。 websockify使用二进制数据的base64编码/解码,并提供用于Javascript的websock.js
库。 websock.js
具有类似于常规WebSocket的API,但它透明地处理二进制数据,旨在与websockify进行通信。 免责声明:我创建了websockify和noVNC。
ssh客户端:
从技术上讲,你可以通过WebSockets实现一个浏览器ssh客户端(我已经考虑过了),但这需要在浏览器中进行SSH加密和解密,这将很慢。鉴于WebSockets具有加密的WSS(TLS)模式,通过WebSocket WSS进行普通的telnet可能更有意义。
事实上,websockify包含一个示例telnet客户端。
您可以像这样在HOSTNAME上启动websockify(telnetd来自krb5-telnetd):
sudo ./websockify 2023 --web . --wrap-mode=respawn -- telnetd -debug 2023
然后导航至http://HOSTNAME:2023/wstelnet.html?hostname=HOSTNAME&port=2023
有关详细信息,请参阅websockify README。要使用WSS加密,您需要按照noVNC advanced usage wiki page
中的说明创建SSL密钥答案 1 :(得分:8)
发送和接收二进制数据的一种好的和安全的方法是使用base64或base128(其中128只有1/7开销而不是1/3)。
是可以使用SSH客户端。
对此的证明是,已经存在许多在常见浏览器中运行的解决方案,但是大多数解决方案仍然需要自定义服务器端实现。 您可以在此处查看更多信息:http://en.wikipedia.org/wiki/Web-based_SSH
答案 2 :(得分:1)
嗯,也许WebSockets可能会以某种方式与此结合:http://ie.microsoft.com/testdrive/HTML5/TypedArrays/
答案 3 :(得分:1)
现在您可以轻松地发送和接收二进制数据,本文解释了许多想法:http://blog.mgechev.com/2015/02/06/parsing-binary-protocol-data-javascript-typedarrays-blobs/
以下是我在浏览器中接收使用python(my_nparray.tobytes())发送的二进制numpy数组的方法:
Path.Combine(FileSystem.Current.LocalStorage.Path, "file.xml")
您可以使用以下方法将类型化数组转换为javascript数组:
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
});
};