Pull to refresh

Бинарный протокол ProtoBuf /AMF и AS3

Reading time4 min
Views1.8K
Не так давно (год назад), google предложил всем желающим использовать язык Protocol Buffers

Почитал, посмотрел — забавно. Перспективы использования большие.
есть порты на AS3, я тестировал этот:http://code.google.com/p/protobuf-actionscript3/

Хочу использовать как замену AMF.
В тестовом примере имитирую передачу данных по бинарному сокету.
Сразу появились проблемы: В том виде, как это сделано сейчас нормально можно работать только по схеме запрос/ответ, т.е. когда знаешь какой класс должен прийти в ответ.
При работе с «безымянным» сокетом в AMF можно узнать что за класс тебе пришел.
Попробуем реализовать это в ProtoBuf:
Все исходники тестового примера во вложении, здесь я акцентирую внимание, только на мои доделки)

итак главный класс: Main.as (читаем комменты)
Код AS3:

  1. package
  2. {
  3. import com.google.protobuf.Message;
  4. import com.google.protobuf.Person;
  5. import com.google.protobuf.PhoneNumber;
  6. import flash.display.Sprite;
  7. import flash.events.Event;
  8. import flash.net.getClassByAlias;
  9. import flash.net.registerClassAlias;
  10. import flash.utils.ByteArray;
  11. import flash.utils.getDefinitionByName;
  12. import flash.utils.getQualifiedClassName;
  13.  
  14. /**
  15. * Тестовый класс работы с protoBuf - изменены исходники класса парсера
  16. * @author k0t0vich
  17. */
  18. public class Main extends Sprite
  19. {
  20.  
  21. public function Main():void
  22. {
  23. if (stage) init();
  24. else addEventListener(Event.ADDED_TO_STAGE, init);
  25. }
  26.  
  27. private function init(e:Event = null):void
  28. {
  29. removeEventListener(Event.ADDED_TO_STAGE, init);
  30. // entry point
  31.  
  32. //Регистрируем псевдонимы классов
  33. registerClassAlias(«py.Person», Person);
  34. registerClassAlias(«py.Number», PhoneNumber);
  35.  
  36. // Создание и шифровка класса.--------------------------
  37. //write
  38. var person:Person = new Person();
  39. person.alias = «py.Person»;
  40. person.setName(«John Doe»);
  41. person.setId(1234);
  42. person.setEmail(«jdoe@example.com»);
  43.  
  44. var number:PhoneNumber = new PhoneNumber();
  45. var number2:PhoneNumber = new PhoneNumber();
  46.  
  47. number.setNumber(«555-6789»);
  48. person.addPhone(number);
  49.  
  50. number2.setNumber(«123123123-12312»);
  51. person.addPhone(number2);
  52.  
  53. trace(«person: »+person);
  54.  
  55. //Write it out to a any IDataOutput
  56. var bytes:ByteArray = new ByteArray();
  57.  
  58. person.writeToDataOutput(bytes);
  59. trace(«writed bytes: » + bytes);
  60. //-------------------------------------------------------
  61.  
  62. // имитация прихода данных от сокета
  63. onData(bytes);
  64.  
  65. }
  66.  
  67. //Данные от
  68. private function onData(bytes:ByteArray):void
  69. {
  70. bytes.position = 0;
  71. //read
  72. var message:Message = new Message();
  73. //читаем не всё сообщение, а только имя псевдонима
  74. var alias:String = message.readClassAliasFromDataOutput(bytes);
  75.  
  76. var classRef:Class = getClassByAlias(alias) as Class;
  77. var item:* = new classRef();
  78.  
  79. bytes.position = 0;
  80. item.readFromDataOutput(bytes);
  81. // выполняем метод конкретного класса
  82. item.changeModel();
  83.  
  84. }
  85. }
  86.  
  87. }

Затем в хэндлере onData (Main.as) вначале читаем имя псевдонима, создаем класс по этому псевдониму и в нём уже, читаем остальные данные

Код AS3:


  1.  
  2. private function onData(bytes:ByteArray):void
  3.         {
  4.             bytes.position = 0; 
  5.             //read
  6.             var message:Message  = new Message();
  7.             //читаем не всё сообщение, а только имя псевдонима
  8.             var alias:String = message.readClassAliasFromDataOutput(bytes);
  9.  
  10.             var classRef:Class = getClassByAlias(alias) as Class;
  11.             var item:* = new  classRef();
  12.  
  13.             bytes.position = 0; 
  14.             item.readFromDataOutput(bytes);
  15.             // выполняем метод конкретного класса
  16.             item.changeModel();    
  17.  
  18.         }

Tags:
Hubs:
-29
Comments4

Articles