コンテキスト: 私はウェブサイトを使用して、自分のウェブサイトのネットサーバーに接続しています。カスタムメソッドがあり、メッセージを処理する方法もカスタムです。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);
}
}
}