在Javascript中通过Web套接字发送和接收二进制数据?

时间:2021-07-08 04:11:30

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客户端吗?

4 个解决方案

#1


45  

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:

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:

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.

    对于在值0-255上均匀分布的二进制数据,有效载荷的大小比原始二进制数据大50%。

  • The Flash WebSockets emulator web-socket-js may have trouble with the encoding of 0 (zero).

    Flash WebSockets模拟器web-socket-js可能在编码0(零)时遇到问题。

Base 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.

    均匀分布的二进制数据(0-255)将比原始数据大33%。

  • 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).

    base64编码的python端开销比UTF-8编码少。但是,解码base64会有更多的Javascript侧开销(UTF-8不需要在Javascript中解码,因为浏览器已经将UTF-8转换为Javascript本机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.

    更新:这假定二进制数据被编码为UTF-8字符串,如上所示,字符值范围为0-255。具体来说,window.atob不支持255以上的字符值。请参阅此mozilla错误。同样的限制适用于Chrome。

websockify:

WebSockify is a proxy/bridge that allows a WebSockets capable browser to communicate with any arbitrary binary service. It was created to allow noVNC to 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编码/解码,并提供了一个用于Javascript的websock.js库。 websock.js有一个类似于常规WebSocket的API,但它透明地处理二进制数据,旨在与websockify进行通信。免责声明:我创建了websockify和noVNC。

ssh client:

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 README for 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高级使用Wiki页面所述

#2


8  

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

#3


1  

Hmm, maybe WebSockets could somehow be combined with this: http://ie.microsoft.com/testdrive/HTML5/TypedArrays/

也许,WebSockets可能会以某种方式与此相结合:http://ie.microsoft.com/testdrive/HTML5/TypedArrays/

#4


1  

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());

#1


45  

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:

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:

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.

    对于在值0-255上均匀分布的二进制数据,有效载荷的大小比原始二进制数据大50%。

  • The Flash WebSockets emulator web-socket-js may have trouble with the encoding of 0 (zero).

    Flash WebSockets模拟器web-socket-js可能在编码0(零)时遇到问题。

Base 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.

    均匀分布的二进制数据(0-255)将比原始数据大33%。

  • 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).

    base64编码的python端开销比UTF-8编码少。但是,解码base64会有更多的Javascript侧开销(UTF-8不需要在Javascript中解码,因为浏览器已经将UTF-8转换为Javascript本机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.

    更新:这假定二进制数据被编码为UTF-8字符串,如上所示,字符值范围为0-255。具体来说,window.atob不支持255以上的字符值。请参阅此mozilla错误。同样的限制适用于Chrome。

websockify:

WebSockify is a proxy/bridge that allows a WebSockets capable browser to communicate with any arbitrary binary service. It was created to allow noVNC to 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编码/解码,并提供了一个用于Javascript的websock.js库。 websock.js有一个类似于常规WebSocket的API,但它透明地处理二进制数据,旨在与websockify进行通信。免责声明:我创建了websockify和noVNC。

ssh client:

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 README for 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高级使用Wiki页面所述

#2


8  

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

#3


1  

Hmm, maybe WebSockets could somehow be combined with this: http://ie.microsoft.com/testdrive/HTML5/TypedArrays/

也许,WebSockets可能会以某种方式与此相结合:http://ie.microsoft.com/testdrive/HTML5/TypedArrays/

#4


1  

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());