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

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

Ответы [ 4 ]

45 голосов
/ 24 апреля 2011

Следующий черновик ( 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 (ноль).

Base 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

Примечания Base 64:

  • Равномерно распределенные двоичные данные (0-255) будут на 33% больше необработанных данных.

  • Тамменьше затрат на стороне Python для кодировки base64, чем для кодировки UTF-8.Однако при декодировании base64 накладные расходы на стороне Javascript немного больше (UTF-8 не требует декодирования в Javascript, поскольку браузер уже преобразовал UTF-8 в собственный UTF-16 Javascript).

  • Обновление : предполагается, что двоичные данные кодируются в строку UTF-8, как показано выше, со значениями символов в диапазоне от 0 до 255.В частности, window.atob не поддерживает значения символов выше 255. См. Эту ошибку mozilla .То же ограничение применяется к Chrome.

websockify :

WebSockify - это прокси / мост, который позволяет WebSockets с поддержкойбраузер для связи с любым произвольным двоичным сервисом.Он был создан, чтобы позволить noVNC обмениваться данными с существующими серверами VNC.websockify использует base64 кодирование / декодирование двоичных данных, а также предоставляет библиотеку 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 для расширенного использования

9 голосов
/ 24 апреля 2011

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

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

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

1 голос
/ 24 марта 2017

Теперь вы можете легко отправлять и получать двоичные данные, в этой статье рассказывается о многом: 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());
1 голос
/ 21 сентября 2012

Хм, может быть, WebSockets можно как-то сочетать с этим: http://ie.microsoft.com/testdrive/HTML5/TypedArrays/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...