Неизвестный тип AMF и другие ошибки при переносе файлов из flash в java - PullRequest
0 голосов
/ 03 ноября 2011

Я использую инструмент Flash для передачи данных на Java. У меня проблемы с отправкой нескольких объектов одновременно. Отправляемые объекты являются просто общими объектными объектами, поэтому нет необходимости регистрировать псевдоним класса или что-либо еще.

Отправка одного объекта работает нормально. Как только я начинаю посылать несколько объектов (помещая одни и те же объекты в массив и отправляя их), это начинает становиться странным. Кажется, что до трех объектов в массиве работают нормально. Более того, я получаю различные ошибки в функции readObject(), например:

  • Неизвестный тип AMF '47'
  • Неизвестный тип AMF '40'
  • Неизвестный тип AMF '20'
  • Индекс исключений OutOfBoundsException 23, размер 0
  • NullPointerException
  • и т.д.

Отправка 3 объектов будет работать, отправка 4 выдаст мне ошибку. Если я удалю один из предыдущих 3, который работал (сохраняя четвертый, который был добавлен), он будет работать снова. Кто-нибудь знает, что происходит?

Дополнительная информация:

  • Связь происходит через класс Socket на стороне Flash. Это чистый AS3, не гибкий.
  • Сообщения сжимаются перед отправкой и распаковываются на сервере, поэтому я почти уверен, что это не проблема размера буфера (если я что-то упустил)
  • BlazeDS версия, кажется, 4.0.0.14931 на банке
  • Flash версия 10.1 (это приложение AIR)

Обновление с приблизительным кодом

Примеры отправляемых объектов:

var o:Object    = { };
o._key          = this._key.toString();
o.someParam     = someString;
o.someParam2    = someInt;
o.someParam3    = [someString1, someString2, someString3];
...

Он добавляется к нашему объекту события (который мы используем для определения события, которое нужно вызвать, данных и т. Д. Для передачи). Объект события зарегистрирован как псевдоним класса

Этот объект отправляется на сервер через сокет следующим образом:

myByteArray.writeObject( eventObj );
myByteArray.compress();
mySocket.writeBytes( myByteArray );
mySocket.flush();

На стороне сервера мы получаем байты и распаковываем их. Мы создаем объект Amf3Input и устанавливаем входной поток, затем читаем его:

Amf3Input amf3Input = new Amf3Input( mySerializationContext );
amf3Input.setInputStream( new ByteArrayInputStream( buffer ) ); // buffer is a byte[]
MyEventObj eventObj = (MyEventObj)amf3Input.readObject(); // MyEventObj is the server version of the client event object

Если происходит сбой с «неизвестной ошибкой типа AMF», это происходит немедленно, т. Е. Когда мы пытаемся прочитать объект, а не когда он пытается прочитать подобъект.

При пошаговом просмотре кода чтения, когда я передаю массив объектов, кажется, что если длина <= 4, он считывает длину правильно. Если длина больше, чем это, это читает его длину как 4. </p>

Ответы [ 2 ]

1 голос
/ 04 ноября 2011

Хорошо, я понял проблему.В основном сообщения сжимаются перед отправкой и распаковываются на сервере.Чего я не видел, так это того, что буфер byte[], в который распаковывалось сообщение, всегда имел длину 1024, что хорошо для небольших массивов объектов.Однако, как только это будет пройдено, он перезапишет буфер (я не совсем уверен, что происходит в Java, когда вы пытаетесь записать больше байтов, чем доступно - независимо от того, возвращается ли он назад или сдвигает данные).

Когда дело дошло до чтения объекта amf, первым делом он читает int и использует его, чтобы определить, какой тип объекта он пытается декодировать.Поскольку этот int был бессмысленным (47, 110, -10), он терпел неудачу.

Время начинать добавлять длины сообщений, я думаю:)

Спасибо за помощь.

1 голос
/ 03 ноября 2011

Если вы получаете ошибки десериализации AMF, есть несколько возможных проблем, которые могут быть причиной этой проблемы.Вот несколько методов для дальнейшей диагностики:

  1. Используйте анализатор сетевого трафика, чтобы убедиться, что то, что вы отправляете, соответствует тому, что вы получаете.На Mac я буду использовать CocoaPacketAnalyzer , или вы можете попробовать Charles , который может фактически декодировать AMF-пакеты, которые он замечает.

  2. Feedданные в другую библиотеку AMF, например PyAMF или RocketAMF , чтобы выяснить, является ли это проблемой с BlazeDS или с тем, как вы ее называете.Также возможно, что вы получите другое сообщение об ошибке, которое даст вам лучшее представление о том, где происходит сбой.

  3. Проверьте формат пакета AMF.Вызовы AMF-сервера имеют некоторую дополнительную оболочку, которая может отбросить десериализатор, если он не ожидает столкновения с этой оболочкой, и наоборот для чисто сериализованных объектов.Пакеты вызовов сервера всегда начинаются с 0x00, за которым следует версия AMF (0x00, 0x03 или, в редких случаях 0x02).

...