BinaryHTTPService или как помочь HTTPService-у принимать ByteArray данные

    В процессе разработки у меня стояла задача найти способ получать бинарные данные от сервера через HTTPService. Сам по себе HTTPService в mx пакете не позволяет получать результат в ByteArray. Это можно увидеть в классе mx.messaging.channels.DirectHTTPChannel в функции internalSend.

    1.  
    2. package mx.messaging.channels
    3. {
    4.   public class DirectHTTPChannel extends Channel
    5.   {
    6.  
    7.     .....
    8.  
    9.     override protected function internalSend(msgResp:MessageResponder):void
    10.     {
    11.         var httpMsgResp:DirectHTTPMessageResponder = DirectHTTPMessageResponder(msgResp);
    12.         var urlRequest:URLRequest;
    13.  
    14.         try
    15.         {
    16.             urlRequest = createURLRequest(httpMsgResp.message);
    17.         }
    18.         catch(e: MessageSerializationError)
    19.         {
    20.             httpMsgResp.agent.fault(e.fault, httpMsgResp.message);
    21.             return;
    22.         }
    23.  
    24.         var urlLoader:URLLoader = httpMsgResp.urlLoader;
    25.         urlLoader.addEventListener(ErrorEvent.ERROR, httpMsgResp.errorHandler);
    26.         urlLoader.addEventListener(IOErrorEvent.IO_ERROR, httpMsgResp.errorHandler);
    27.         urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, httpMsgResp.securityErrorHandler);
    28.         urlLoader.addEventListener(Event.COMPLETE, httpMsgResp.completeHandler);
    29.         urlLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpMsgResp.httpStatusHandler);
    30.         urlLoader.load(urlRequest);
    31.     }
    32.    
    33.     .....
    34.    
    35.   }
    36. }
    37.  

    У URLLoader-а по умолчанию параметр dataFormat имеет значение URLLoaderDataFormat.TEXT, а для получение данных в виде ByteArray на нужен URLLoaderDataFormat.BINARY.

    Всё делается очень просто. Первое, что нам нужно – это создать расширение для класса DirectHTTPChannel и установить у urlLoader-а параметр dataFormat=URLLoaderDataFormat.BINARY;
    1.  
    2. public class DirectHTTPBinaryChannel extends DirectHTTPChannel
    3. {
    4.     public function DirectHTTPBinaryChannel(id:String, uri:String="")
    5.     {
    6.         super(id, uri);
    7.     }
    8.  
    9.     override protected function getMessageResponder(agent:MessageAgent,
    10.                                                     message:IMessage):MessageResponder
    11.     {
    12.         return new DirectHTTPBinaryMessageResponder(agent, message, this, new URLLoader());
    13.     }
    14.  
    15.     override protected function internalSend(msgResp:MessageResponder):void
    16.     {
    17.         var httpMsgResp:DirectHTTPBinaryMessageResponder = DirectHTTPBinaryMessageResponder(msgResp);
    18.         var urlRequest:URLRequest;
    19.  
    20.         try
    21.         {
    22.             urlRequest = createURLRequest(httpMsgResp.message);
    23.         }
    24.         catch(e: MessageSerializationError)
    25.         {
    26.             httpMsgResp.agent.fault(e.fault, httpMsgResp.message);
    27.             return;
    28.         }
    29.  
    30.         var urlLoader:URLLoader = httpMsgResp.urlLoader;
    31.         urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
    32.         urlLoader.addEventListener(ErrorEvent.ERROR, httpMsgResp.errorHandler);
    33.         urlLoader.addEventListener(IOErrorEvent.IO_ERROR, httpMsgResp.errorHandler);
    34.         urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, httpMsgResp.securityErrorHandler);
    35.         urlLoader.addEventListener(Event.COMPLETE, httpMsgResp.completeHandler);
    36.         urlLoader.load(urlRequest);
    37.     }
    38. }
    39.  

    Для того чтобы мы могли использовать наш DirectHTTPBinaryChannel, создаем расширение класса HTTPService.
    1.  
    2. public class BinaryHTTPService extends HTTPService
    3. {
    4.   protected static var binaryChannel:Channel;
    5.   protected static var binaryChannelSet:ChannelSet;
    6.  
    7.   public function BinaryHTTPService(rootURL:String = null, destination:String = null)
    8.   {
    9.     super(rootURL, destination);
    10.   }
    11.  
    12.   override public function send(parameters:Object = null):AsyncToken
    13.   {
    14.     if (useProxy == false)
    15.     {
    16.       /* force the use of our binary channel */
    17.       if (binaryChannelSet == null)
    18.       {
    19.         var dcs:ChannelSet = new ChannelSet();
    20.         binaryChannel = new DirectHTTPBinaryChannel("direct_http_binary_channel");
    21.         dcs.addChannel(binaryChannel);
    22.         channelSet = dcs;
    23.         binaryChannelSet = dcs;
    24.       }
    25.       else if (channelSet != binaryChannelSet)
    26.       {
    27.         channelSet = binaryChannelSet;
    28.       }
    29.     }
    30.     return super.send(parameters);
    31.   }
    32. }
    33.  

    Пример рабочих классов: BinaryHTTPService DirectHTTPBinaryChannel

    Комментарии 5

      0
      Спасибо. Полезно :)

      Интересно как оно в pure as3.
        0
        В pure не получиться, т.к. HTTPService является частью Flex SDK.
          0
          Понимаю, поэтому и задумался)
            0
            Ну в принципе можно написать свой HTTPService на чистом as3, попроще чем во Flex (он у них какой-то монстроподобный).
              0
              Как руки дойдут, напишу )

      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

      Самое читаемое