2016-11-01 8 views
0

コンテキスト: 私はウェブサイトを使用して、自分のウェブサイトのネットサーバーに接続しています。カスタムメソッドがあり、メッセージを処理する方法もカスタムです。WebSocketのespecifcメソッドの変更検出をキャンセルするにはどうすればよいですか?

送信したいメッセージが大きすぎる場合は、それを複数の小さなメッセージに分割して、1つのソケットで '並列'メッセージを送信できるようにします。 この部分は細かい

問題を取り組んでいる: 「メッセージ部分が」のWebSocketに達するたびに、それはデコードされ、実際のメッセージに連結する「MessageDecoder」に入り、(私は仮定)のトリガーをzones.jsページワイド変化検出。これはwebsocketがメッセージの部分を処理できるように速く起こるので、アプリケーション全体がクロールされるのが遅くなり、メッセージ全体が完了してコールバックが呼び出されるまでアプリケーションの変更は一切行われません変更)。 ファイルをダウンロードすると、通常は最後にアプリケーションに変更を加えることができるメッセージ部分が6000個になります。

「this.zone.runOutsideAngular(()=> {'をコードに盲目的に追加しようとしましたが、修正できませんでした。 zone.jsが変更検出をトリガすることを決定したとき、私はかなり理解していません。以下のコードでは、変更検出を引き起こすはずのコードを示すコメントしかありません。

OBS:後で「yyyパーツのxxxxxxxxxxxxxxxxxxxxメッセージを追加する」(ダウンロードバーを作成する)ので、変更検出をトリガーする必要があります。このメソッド/変数はページ全体ではなく変更をチェックします

コード:

import { Injectable, NgZone } from '@angular/core'; 

declare var MessageDecoder: any; 
declare var MessageEncoder: any; 
declare var GetMessageTranslator: any; 
declare var TextDecoder: any; 
declare var DataStream: any; 
declare var StatusCheck: any; 
@Injectable() 
export class ConnectionService { 
    public connection: any; 
    private status: boolean; 
    public ping: number; 
    public errorState: number; 
    public interval: number; 

    constructor(private zone: NgZone) { 
     this.startAutoConnect(); 
    } 

    public getState() { 
     if (this.connection == undefined) { 
      return "offline"; 
     } 
     if (this.errorState > new Date().getTime()) { 
      return "error"; 
     } 
     if (this.connection.readyState != WebSocket.OPEN) { 
      return "offline"; 
     } else { 
      if (this.status) { 
       return "loggedIn"; 
      } else { 
       return "connected"; 
      } 
     } 
    } 
    autoConnectHandle: any; 
    waitForSocketConnection(socket, callback) { 
     setTimeout(
      function() { 
       if (socket.readyState === 1) { 
        if (callback !== undefined) { 
         callback(); 
        } 
        return; 
       } else { 
        this.waitForSocketConnection(socket, callback); 
       } 
      }, 5); 
    }; 
    onOpen1 = function() { 
     this.aThis.onOpen(this.aThis); 
    } 
    onOpen = function() { 
     this.waitForSocketConnection(this.connection,() => { 
      clearInterval(this.autoConnectHandle); 
      this.autoConnectHandle = undefined; 
      var connection: any = this.connection; 
      var aThis: ConnectionService = this; 
      connection.onclose = function() { 
       aThis.startAutoConnect(); 
      } 
      connection.supersend = connection.send; 
      connection.send = function(message, callback, type) { 
       if (message.ID == undefined) { 
        message.configure(); 
        message.init(this); 
       } 
       if (this.promiseMap[message.getRequestID()] == undefined) { 
        this.promiseMap[message.getRequestID()] = { 
         type: type, 
         callback: callback, 
         complete: false 
        }; 
       } 
       message.writeToChannel(this); 
      } 
      connection.attr = {}; 
      connection.promiseMap = {}; 

      connection.onerror = function(error) { 
       this.errorState = new Date().getTime() + 1500; 
       console.error('WebSocket Error ' + error); 
      }; 
      connection.channelRead = function(message) {//called by the message decoder after the message is complete 
       console.log("got: " + message.getClass()); 
       var promisse = this.promiseMap[message.getRequestID()]; 
       if (promisse != undefined) { 
        if (promisse.complete) { 
         return; 
        } else { 
         if (promisse.type == message.getClass() || promisse.type == undefined) { 
          if (promisse.callback != undefined) { 
           //THIS SHOULD TRIGGER THE CHANGE DETECTION, ANYTHING ELSE MEANS THAT IT WAS 
           //A MESSAGE THAT DON'T CARE ABOUT THE RESULT, SO NOTHING WILL CHANGE BECAUSE 
           //OF IT 
           promisse.callback(message); 
          } 
          promisse.complete = true; 
          delete this.promiseMap[message.getRequestID()]; 
         } else if (message.getClass() == "NullServerMessage") { 

         } 
        } 
        var answer = message.processAnswer(this); 
        if (answer.getClass() != "NullServerMessage") { 
         console.log("sent: " + answer.getClass()); 
         this.send(answer); 
        } 
       } 
      } 
      connection.decoder = new MessageDecoder(); 
      connection.encoder = new MessageEncoder(); 

      connection.onmessage = (e) => { 
       //I believe this is triggering the excess of change detections 
       var arrayBuffer; 
       var fileReader = <any>new FileReader(); 
       fileReader.onload = function() { 
        connection.decoder.decode(connection, new DataStream(this.result), undefined) 
       }; 
       fileReader.readAsArrayBuffer(e.data); 
      }; 
      aThis.interval = setInterval(() => new function() { 
       connection.pingCounter = new Date().getTime(); 
       connection.send(new StatusCheck(), function(message) { 
        aThis.status = message.status; 
        aThis.ping = new Date().getTime() - connection.pingCounter; 
       }); 
      }, 1000); 
      connection.send(new GetMessageTranslator(), function(message) { 
       connection.decoder.translator = message.map; 
       connection.encoder.translator = message.map; 
       connection.encoder.translator.getKeyByValue = function(value) { 
        for (var prop in this) { 
         if (this.hasOwnProperty(prop)) { 
          if (this[prop] === value) 
           return prop; 
         } 
        } 
       } 

      }); 
     }); 
    } 

    startAutoConnect() { 
     if (this.connection) { 
      this.connection.close(); 
      if (this.interval != undefined) { 
       clearInterval(this.interval); 
       this.interval = undefined; 
      } 
      this.connection = undefined; 
     } 
     var connection: any; 
     var aThis: ConnectionService = this; 
     if (!this.autoConnectHandle) { 
      this.autoConnectHandle = setInterval(() => new function() { 
       if (this.connection == undefined) { 
        aThis.connection = connection = new WebSocket('ws://localhost:80/websocket'); 
        connection.aThis = aThis; 
        connection.onopen = aThis.onOpen1; 
        connection.onerror = function(error) { 
         aThis.startAutoConnect(); 
        }; 
       } 
      }, 1500); 
     } 
    } 

} 

答えて

0

私は何もほかのWebSocketの呼び出しに応じて更新されなかったよう

constructor(private zone: NgZone) { 
    this.zone.runOutsideAngular(() => { 
     this.startAutoConnect(); 
    }); 
} 

constructor(private zone: NgZone) { 
    this.startAutoConnect(); 
} 

を変更することで、これが行われ、私はそれを得たと思いますpingカウンタを更新し、私のwebsocketメッセージからの結果は、pingカウンタも更新されただけで更新されました。これは実際にはうまくいきました。メッセージはn私が望んでいたように、変化の検出を引き起こすことはありません。

問題は、ダウンロード中にすべてが極端に遅くなってしまうという本来の問題が残っていたため、これは決してその原因ではなかったということです。

    if (promisse.type == message.getClass() || promisse.type == undefined) { 
         if (promisse.callback != undefined) { 
          this.aThis.zone.run(() => { 
           promisse.callback(message); 
          }); 
         } 
         promisse.complete = true; 
         delete this.promiseMap[message.getRequestID()]; 

    if (promisse.type == message.getClass() || promisse.type == undefined) { 
         if (promisse.callback != undefined) { 
          //THIS SHOULD TRIGGER THE CHANGE DETECTION, ANYTHING ELSE MEANS THAT IT WAS 
          //A MESSAGE THAT DON'T CARE ABOUT THE RESULT, SO NOTHING WILL CHANGE BECAUSE 
          //OF IT 
          promisse.callback(message); 
         } 
         promisse.complete = true; 
         delete this.promiseMap[message.getRequestID()]; 

を変更

は、変化検出は、メッセージが完了したたびに起こると完成処理をコールバックしました。

関連する問題