How to cancel change detection for a especifc method of a WebSocket?

Context: I am using a websocket to connect to a netty server for my website. I have custom methods and the way I handle messages is also custom.

If a message I want to send is too big, I will split it into many small messages, so that a single socket can send 'parallel' messages. This part is working fine

Problem: Every time a 'message part' reaches the websocket, it goes into a 'MessageDecoder' to be decoded and concatenated into an actual message, the (I assume) zones.js triggers a page wide change detection. Since this happens as fast as the websocket can process the message parts, it slows the whole application to a crawl, worse still, nothing on the application ever changes until the whole message is completed and THEN the callbacks called (which are the ones that cause the changes). Downloading a file usually results in 6000 message parts, where only the last one can ever hope to make any change to the application.

I have already tried to blindly add 'this.zone.runOutsideAngular(() => {' to the code, but I couldn't fix it. I don't quite understand where it's applicable to use that, since I don't quite understand when zones.js decides to trigger the change detection. In the code below, there will be a comment that indicates the ONLY piece of code that should EVER trigger a change detection.

OBS: I might want to later add a 'the message with id zzz received xxx of yyy parts' counter (to make a download bar), so that would also need to trigger a change detection. But hopefully it's possible to ensure that only those who are listening to this method/variable will check for changes, rather than the whole page

Code:

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);
        }
    }

}


ANSWERS:


I think I got it, by changing

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

to

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

This made so that nothing was updating in response to the websocket calls besides the ping counter, and the result from my websocket messages was only updated once the ping counter updated too, which makes me thing that indeed it worked, the messages were not triggering the change detection, sorta like I wanted.

The problem is that the original problem of everything getting super slow during downloads persisted, so this was never the cause of it.

changing

                    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()];

to

                    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()];

made the change detection happen every time a message was complete and callback finished processing.



 MORE:


 ? How to change the Time zone
 ? TextField focus() not working
 ? TextField focus() not working
 ? TextField focus() not working
 ? OnBlur event without the ngModel & textfield blinking
 ? How to use nativescript's WebView in angular2?
 ? How to use nativescript's WebView in angular2?
 ? How to use nativescript's WebView in angular2?
 ? Nativescript bare webview doesnt seem to work
 ? How to resize the container's height of listviewitem of Telerik UI for UWP