Ответ 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 расширенной вики-страницы