Получить бинарный файл с paho mqttws31.js

Я использую paho: http://www.eclipse.org/paho/clients/js/ lib для подключения к mqtt-брокеру. Но когда я получаю двоичные данные через веб-сокеты, он говорит, что мои данные искажены: Ошибка: AMQJS0009E Неверные данные UTF: d4 -3f . . Нельзя ли получить бинарник с paho mqttws31.js

Изменить: к сожалению, я использовал (message.payloadString) для получения полученного сообщения. Но насколько я понимаю(https://github.com/i5ting/paho.mqtt.javascript/blob/master/src/mqttws31.js#L2060) также можно использовать message.payloadBytes.

Так что на самом деле я отправляю Doubles, каждый из которых имеет 8 байтов. Как я могу получить к ним доступ в message.payloadBytes?

Спасибо.


person dan kutz    schedule 28.08.2014    source источник


Ответы (1)


Вы, вероятно, хотите взглянуть на это:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays

Из этого видно, что вы должны быть в состоянии сделать что-то вроде этого:

var payload = message.payloadByte()
var doubleView = new Float64Array(payload);
var number = doubleView[0];

Это предполагает, что полезная нагрузка сообщения представляет собой одно 64-битное число с плавающей запятой IEEE.

Другой возможный вариант - посмотреть ответ на этот предыдущий вопрос:

Чтение/запись байтов с плавающей запятой в JS

РЕДАКТИРОВАТЬ:

У меня работает следующий код:

function onMessageArrived(message) {
  var payload = message.payloadBytes
  var length = payload.length;
  var buffer = new ArrayBuffer(length);
  uint = new Uint8Array(buffer);
  for (var i=0; i<length; i++) {
      uint[(length-1)-i] = payload[i];
  }
  var doubleView = new Float64Array(uint.buffer);
  var number = doubleView[0];
  console.log("onMessageArrived:"+number);
};

Обратите внимание, что мне пришлось изменить порядок байтов, чтобы получить правильный вывод.

РЕДАКТИРОВАТЬ 2

Это работает лучше и будет декодировать произвольные длины массивов двойников:

function onMessageArrived(message) {
  var payload = message.payloadBytes
  var length = payload.length;
  var buffer = new ArrayBuffer(length);
  uint = new Uint8Array(buffer);
  for (var i=0; i<length; i++) {
      uint[i] = payload[i];
  }
  var dataView = new DataView(uint.buffer);
  for (var i=0; i<length/8; i++) {
      console.log(dataView.getFloat64((i*8), false));
  }
};

(вам может потребоваться перевернуть false на true в конце dataView.getFloat64() в зависимости от порядка байтов отправляющей платформы)

Полный текст кода, который я написал для этого, можно найти здесь: http://www.hardill.me.uk/wordpress/2014/08/29/unpacking-binary-data-from-mqtt-in-javascript/

person hardillb    schedule 29.08.2014
comment
Хорошо, я думаю, что это следующая проблема: я хочу преобразовать Uint8Array[256] в массив с плавающей запятой, каждый элемент которого имеет длину 8 байт. Таким образом, это массив длиной 32 значения (256/8), каждое значение представляет собой тип Double/Float с 8 байтами. - person dan kutz; 29.08.2014
comment
Большое спасибо. Это часть оптимизации внутри локальной сети и я получил прирост производительности на 20-30%. Поскольку это примерно половина отправляемых двоичных данных по сравнению с JSON.strinify(data), это может быть очень удобно для огромных объемов данных, передаваемых в Интернете. Однако мне интересно, можно ли оптимизировать и этот код, потому что он состоит из двух циклов for и резервирует в два раза больше памяти. - person dan kutz; 30.08.2014
comment
поэтому я думаю, что это самый эффективный способ получить данные? - person dan kutz; 02.09.2014