Подтвердить что ты не робот

Отправлять и получать двоичные данные через веб-сокеты в Javascript?

Можно отправлять и получать двоичные данные через веб-сокеты в Javascript? Могу ли я, например, реализовать SSH-клиент, используя веб-сокеты?

4b9b3361

Ответ 1

Следующий проект (hybi-07) спецификации WebSockets реализуется в большинстве браузеров, и он добавит встроенную двоичную поддержку для протокол и API.

Однако до тех пор, полезная нагрузка WebSockets кодируется как UTF-8. Для отправки двоичных данных вы должны использовать некоторый способ кодирования двоичных данных как UTF-8.

Есть много вариантов, но вот два, которые я использовал:

UTF-8:

Фактически вы можете кодировать поток байтов непосредственно в UTF-8.

Питон для кодирования и декодирования будет выглядеть примерно так:

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. Это ограничение распространяется и на Chrome.

websockify

WebSockify - это прокси-мост, который позволяет браузеру, совместимому с WebSockets, обмениваться данными с любой произвольной бинарной службой. Он был создан для обеспечения noVNC для связи с существующими серверами VNC. websockify использует base64 encode/decode двоичных данных, а также предоставляет библиотеку websock.js для использования в Javascript. websock.js имеет API, похожий на обычный WebSocket, но он прозрачно обрабатывает двоичные данные и предназначен для связи с websockify. Отказ от ответственности. Я создал websockify и noVNC.

клиент ssh:

Технически вы можете реализовать клиентский ssh-клиент через WebSockets (и я его рассмотрел), однако для этого потребуется сделать SSH-шифрование и дешифрование в браузере, который будет медленным. Учитывая, что WebSockets имеет зашифрованный WSS (TLS) режим, вероятно, имеет смысл делать простой telnet через WebSocket WSS.

Фактически, websockify включает пример telnet-клиента.

Вы запустили бы websockify в HOSTNAME, как это (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, вам необходимо создать ключ SSL, как описано на странице noVNC расширенной вики-страницы

Ответ 2

Одним хорошим и безопасным способом отправки и получения двоичных данных является base64 или base128 (где 128 имеет только 1/7 служебных данных вместо 1/3).

Да, возможен SSH-клиент.

Доказательством этого является то, что уже существует множество решений, которые выполняются в обычных браузерах, но для большинства из них по-прежнему требуется специальная реализация на стороне сервера. Вы можете посмотреть здесь для получения дополнительной информации: http://en.wikipedia.org/wiki/Web-based_SSH

Ответ 4

Теперь вы можете легко отправлять и получать двоичные данные, в этой статье объясняется много идей: http://blog.mgechev.com/2015/02/06/parsing-binary-protocol-data-javascript-typedarrays-blobs/

Вот как я получаю массив двоичных numpy, отправленный с python (my_nparray.tobytes()) в моем браузере:

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

Вы можете преобразовать типизированный массив в массив javascript с помощью этого:

Array.prototype.slice.call(buffer.slice());