Можно отправлять и получать двоичные данные через веб-сокеты в Javascript? Могу ли я, например, реализовать SSH-клиент, используя веб-сокеты?
Отправлять и получать двоичные данные через веб-сокеты в Javascript?
Ответ 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
Ответ 3
Хм, возможно, WebSockets можно каким-то образом сочетать с этим: http://ie.microsoft.com/testdrive/HTML5/TypedArrays/
Ответ 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());