LocalConnectionを介して40キロバイト以上を転送します

LocalConnectionを介して相互接続された個別の.swfで構成されるFlashプロジェクトの成長に伴い、送信されるデータのサイズの必要性が増加する可能性があります。 たとえば、ゲームと別のメッセージアプリケーション間で送信されたメッセージからのデータ交換があります。



送信データが40 Kbを超えると問題が始まり、エラーが表示され、アプリケーションが正常に動作しなくなります。



sendメソッドでパラメーターとして送信できるデータの量は40キロバイトに制限されていることを思い出させてください。



この状況から抜け出す方法はいくつかあります。

  1. ローカル共有オブジェクトを使用します。
  2. JavaScriptを使用してデータを転送します。
  3. LocalConnectionを介してデータをパーツに分割して転送します。




最初の2つのポイントには、最後のポイントよりも大きな変更が必要です。 したがって、最小限のコストで、40 Kb未満の部品でのデータ転送を実現します。



送信されるデータの構造:

  1. unsigned int-メッセージ全体のデータ長。
  2. unsigned int-オブジェクトのデータ長。
  3. シリアル化されたオブジェクトデータ。




すべてのデータを正しく収集するために、LocalConnectionクライアントのラッパーを作成します。

public class ExtendedClient { private var receivedData:ByteArray = new ByteArray(); private var length:int = -1; /**   - */ private var client:Object; public function ExtendedClient(client:Object) { this.client = client; } /** *   . * @param packet -  . */ public function reciverLocalConnection(packet:ByteArray):void { //     if(length == -1) length = packet.readUnsignedInt(); packet.readBytes(receivedData, receivedData.length, packet.length - packet.position); //      if(receivedData.length == length) { //    deserialization(receivedData); receivedData = new ByteArray(); length = -1; } } /** *  . * @param receivedData -  . */ protected function deserialization(receivedData:ByteArray):void { var parameters:Array = new Array(); var temp:ByteArray = new ByteArray(); while(receivedData.position != receivedData.length) { receivedData.readBytes(temp, 0, receivedData.readUnsignedInt() - 4); parameters.push(temp.readObject()); temp.clear(); } try { //      (client[parameters[0]] as Function).apply(this, parameters.slice(1)); }catch(error:ReferenceError) { trace("Error:", error.message); } } }
      
      





次に、標準のLocalConnectionクラスを展開し、sendメソッドに渡されるすべての引数のサイズを考慮してデータを転送します。



 public class ExtendedLocalConnect extends LocalConnection { private static const METHOD_NAME:String = "reciverLocalConnection"; /**    */ private var _blockWeight:int; private var _complete:Boolean = true; public function ExtendedLocalConnect() { super(); } /** *   . * @param localConnectionName -  . * @param args - ,      . */ public function write(localConnectionName:String, ... args):void { // 63         _blockWeight = 40897 - localConnectionName.length - METHOD_NAME.length; _complete = false; var bytes:ByteArray = new ByteArray(); //       bytes.writeUnsignedInt(0); //    for(var i:int = 0, n:int = args.length; i < n; i++) { var startPosition:int = bytes.position; bytes.writeUnsignedInt(0); bytes.writeObject(args[i]); bytes.position = startPosition; //     bytes.writeUnsignedInt(bytes.length - startPosition); bytes.position = bytes.length; } bytes.position = 0; //    bytes.writeUnsignedInt(bytes.length - 4); bytes.position = 0; var bytesLength:int = bytes.length; var currentPosition:int = 0; var currentLength:int = bytesLength; while(currentLength > 0) { var packageLength:int = (currentLength > _blockWeight)? _blockWeight: currentLength; var packet:ByteArray = new ByteArray(); //    bytes.readBytes(packet, 0, packageLength); currentPosition += packageLength; currentLength = bytesLength - currentPosition; if(!currentLength) _complete = true; //   send(localConnectionName, METHOD_NAME, packet); } bytes.clear(); } public function set target(extendedClient:ExtendedClient):void { client = extendedClient; } public function get complete():Boolean { return _complete; } }
      
      







完全なプロパティが必要な理由を説明しましょう。データを送信するたびに、sendメソッドはStatusEvent.STATUSイベントを発生させます。 この場合、1つのメッセージでこのようなイベントを多数作成できるため、メッセージが送信されたことを判断するために、完了状態を書き込みます。

使用例:

 var extendedLocalConnection:ExtendedLocalConnect = new ExtendedLocalConnect(); var client:ExtendedClient = new ExtendedClient(this); extendedLocalConnection.target = client; //   extendedLocalConnection.connect("myConnection"); //   extendedLocalConnection.write("myConnection", "myFunction", data);
      
      









受信者の結果





オブジェクトを送信した結果



したがって、標準のLocalConnectionを簡単に置き換えて、データ転送の制限を回避できます。 また、データ転送の標準メソッドを使用する必要がある場合は、ExtendedClientクラスを拡張して、追加の呼び出しメソッドを記述することができます。

UPD:接続の名前と呼び出されたメソッドの名前に応じて、使用可能なブロックサイズの自動検出を追加しました。



All Articles