Websockets clients crash on high message rate - javascript

My javascript websocket client crashes when it is receiving messages at a high rate. I've tried 3 browsers and they all crash. Chrome as first, IE second and Edge can keep up a little longer.
The messagerate is about 30 messages in less then a second. All about 10-20 chars long (data-part).
Are the onmessage calls async? And can they run parallel (next onmessage already starts before the previous is done) or are the requests placed in some sort of queue?
I've tried to "block" the onMessage to no avail.
var blockWS = false;
function pageLoad() {
if ('WebSocket' in window) {
var ws = new WebSocket(((window.location.protocol === 'https:') ? 'wss://' : 'ws://') + window.location.host + '/ws');
ws.onmessage = function(message) {
while (blockWS) {
// wait
}
blockWS = true;
var el = document.getElementById('printer');
el.innerHTML += message.data;
el.scrollTop = el.scrollHeight;
blockWS = false;
};
} else {
// The browser doesn't support WebSocket
document.getElementById('body').innerHTML = '<h1>Your browser does not support WebSocket.</h1>';
}
}
<html>
<body onload="pageLoad()">
<div id="body">
<div id="printer"></div>
</div>
</body>
</html>

The easy (not sure about performance here) way to do what you're wanting to do is to use the setInterval() method outside of the loop and simply store the array of messages as they come in from the websockets. Here is some test code that you could do:
EDIT: I added an updated part of the code so that the insert into the DOM will only happen if there are new messages that need to be shown.
// Your code that is crashing the browser:
/*var blockWS = false;
function pageLoad() {
if ('WebSocket' in window) {
var ws = new WebSocket(((window.location.protocol === 'https:') ? 'wss://' : 'ws://') + window.location.host + '/ws');
ws.onmessage = function(message) {
while (blockWS) {
// wait
}
blockWS = true;
var el = document.getElementById('printer');
el.innerHTML += message.data;
el.scrollTop = el.scrollHeight;
blockWS = false;
};
} else {
// The browser doesn't support WebSocket
document.getElementById('body').innerHTML = '<h1>Your browser does not support WebSocket.</h1>';
}
}*/
// Using the setInterval method (I used 1s, but you can change that to your preferences):
function pageLoad() {
const MESSAGE_INSERT_TIME_MS = 1000;
let messages = [];
let intervalId = null;
if ('WebSocket' in window) {
const protocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
const ws = new WebSocket(`${protocol}${window.location.host}/ws`);
ws.onmessage = (message) => {
messages.push(message);
};
// At any point inside the "pageLoad()" function, you can use "intervalId.clearInterval()" to stop doing this function.
intervalId = setInterval(() => {
const el = document.getElementById('printer');
if (!el.innerHTML === messages.join('')) {
el.innerHTML = messages;
el.scrollTop = el.scrollHeight;
}
}, MESSAGE_INSERT_TIME_MS);
}
}

Related

What is wrong with my JS webassemblity player?

I am trying to port a C++ program to WASM using emscripten.
The compilation process has been mastered, but so far with the presentation, which is bad ... I have
problem:
Uncaught ReferenceError: request is not defined
request.onload = function() {
Here is my script:
<script type='text/javascript'>
request.onload = function() {
var bytes = request.response;
fetch('hello.wasm').then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, importObject)
).then(results => {
// Do something with the results!
console.log(results);
});
};
var statusElement = document.getElementById('status');
var progressElement = document.getElementById('progress');
var spinnerElement = document.getElementById('spinner');
var Module = {
preRun: [],
postRun: [],
print: (function() {
var element = document.getElementById('output');
if (element) element.value = ''; // clear browser cache
return function(text) {
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
// These replacements are necessary if you render to raw HTML
//text = text.replace(/&/g, "&");
//text = text.replace(/</g, "<");
//text = text.replace(/>/g, ">");
//text = text.replace('\n', '<br>', 'g');
console.log(text);
if (element) {
element.value += text + "\n";
element.scrollTop = element.scrollHeight; // focus on bottom
}
};
})(),
canvas: (function() {
var canvas = document.getElementById('canvas');
// As a default initial behavior, pop up an alert when webgl context is lost. To make your
// application robust, you may want to override this behavior before shipping!
// See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
return canvas;
})(),
setStatus: function(text) {
if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' };
if (text === Module.setStatus.last.text) return;
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
var now = Date.now();
if (m && now - Module.setStatus.last.time < 30) return; // if this is a progress update, skip it if too soon
Module.setStatus.last.time = now;
Module.setStatus.last.text = text;
if (m) {
text = m[1];
progressElement.value = parseInt(m[2])*100;
progressElement.max = parseInt(m[4])*100;
progressElement.hidden = false;
spinnerElement.hidden = false;
} else {
progressElement.value = null;
progressElement.max = null;
progressElement.hidden = true;
if (!text) spinnerElement.style.display = 'none';
}
statusElement.innerHTML = text;
},
totalDependencies: 0,
monitorRunDependencies: function(left) {
this.totalDependencies = Math.max(this.totalDependencies, left);
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
}
};
Module.setStatus('Downloading...');
window.onerror = function(event) {
// TODO: do not warn on ok events like simulating an infinite loop or exitStatus
Module.setStatus('Exception thrown, see JavaScript console');
spinnerElement.style.display = 'none';
Module.setStatus = function(text) {
if (text) Module.printErr('[post-exception status] ' + text);
};
};
</script>
(updated: right code) here is my source of testing site:
https://www.dropbox.com/sh/elgdplx8xmvp51g/AAC-M0oCrA0_rgWZfrRvMt8na?dl=0 look at hello.html
Unfortunately request is not a "standard variable of connection" and is not special in any way. What you probably want is window.onload which is a global event handler available on the window object.
window is a special variable and does have the onload event handler available.
Take a look at the documentation for onload
<script type='text/javascript'>
window.onload = function() {
var bytes = request.response;
fetch('hello.wasm').then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, importObject)
).then(results => {
// Do something with the results!
console.log(results);
});
};
// Rest of your code ...
Finally a have successfuly build the program and my script now looking just only.
<script src=./a.out.js>
I have update files on my dropbox-link to test project folder for more info. https://www.dropbox.com/sh/elgdplx8xmvp51g/AAC-M0oCrA0_rgWZfrRvMt8na?dl=0
In two words it separate script for two parts in the ending of html page
1st is
<script type='text/javascript'>
var statusElement = document.getElementById('status');
var progressElement = document.getElementById('progress');
var spinnerElement = document.getElementById('spinner');
var Module = {
preRun: [],
postRun: [],
print: (function() {
var element = document.getElementById('output');
if (element) element.value = ''; // clear browser cache
return function(text) {
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
// These replacements are necessary if you render to raw HTML
//text = text.replace(/&/g, "&");
//text = text.replace(/</g, "<");
//text = text.replace(/>/g, ">");
//text = text.replace('\n', '<br>', 'g');
console.log(text);
if (element) {
element.value += text + "\n";
element.scrollTop = element.scrollHeight; // focus on bottom
}
};
})(),
printErr: function(text) {
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
if (0) { // XXX disabled for safety typeof dump == 'function') {
dump(text + '\n'); // fast, straight to the real console
} else {
console.error(text);
}
},
canvas: (function() {
var canvas = document.getElementById('canvas');
// As a default initial behavior, pop up an alert when webgl context is lost. To make your
// application robust, you may want to override this behavior before shipping!
// See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
return canvas;
})(),
setStatus: function(text) {
if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' };
if (text === Module.setStatus.text) return;
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
var now = Date.now();
if (m && now - Date.now() < 30) return; // if this is a progress update, skip it if too soon
if (m) {
text = m[1];
progressElement.value = parseInt(m[2])*100;
progressElement.max = parseInt(m[4])*100;
progressElement.hidden = false;
spinnerElement.hidden = false;
} else {
progressElement.value = null;
progressElement.max = null;
progressElement.hidden = true;
if (!text) spinnerElement.style.display = 'none';
}
statusElement.innerHTML = text;
},
totalDependencies: 0,
monitorRunDependencies: function(left) {
this.totalDependencies = Math.max(this.totalDependencies, left);
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
}
};
Module.setStatus('Downloading...');
window.onerror = function(event) {
// TODO: do not warn on ok events like simulating an infinite loop or exitStatus
Module.setStatus('Exception thrown, see JavaScript console');
spinnerElement.style.display = 'none';
Module.setStatus = function(text) {
if (text) Module.printErr('[post-exception status] ' + text);
};
};
</script>
and the second one is just
<script src=./a.out.js>
full of text you cant see on link to dropbox? its a lot of code to post here
and 3rd this is that i have copy from emscripter git repo html document that it must generate (but in my way not) and also put it to drop box link, to not to spam here.

Why does this barcode detection cause Chrome or the whole Android OS to crash?

I built a barcode scanning system using Chrome's built-in BarcodeDetector. I based the work on Paul Kinlan's QR code scanner which works fine on my phone, but when I run my own code on my phone, it often causes Chrome or the whole System UI to freeze. Sometimes it gets so bad that I need to restart the phone by holding down the power button.
I have tried debugging in the Chrome developer console, but when the phone freezes, so does the developer console.
When I comment out the actual QR code detection, I can leave the page open in Chrome for 10 minutes and it just keeps running. With QR code detection running, the phone will freeze anywhere from immediately to 3 minutes later.
I put the support files (js and HTML) in a Gist - I don't think they are the issue because everything works when the barcode scanning is commented out.
My first attempt:
// Inspired by/based on on https://github.com/PaulKinlan/qrcode/blob/production/app/scripts/main.mjs
import WebCamManager from './scan/WebCamManager.js';
(function () {
'use strict';
var QRCodeCamera = function (element) {
var root = document.getElementById(element);
var cameraRoot = root.querySelector('.CameraRealtime');
var cameraManager = new WebCamManager(cameraRoot);
var cameraVideo = root.querySelector('.Camera-video');
// Offscreen canvas is supposed to help with processing speed
var cameraCanvas = new OffscreenCanvas(1,1);
var context = cameraCanvas.getContext('2d');
const detector = new BarcodeDetector({
formats: ['qr_code'],
});
cameraManager.onframeready = async function (frameData) {
cameraCanvas.width = cameraVideo.videoWidth;
cameraCanvas.height = cameraVideo.videoHeight;
context.drawImage(frameData, 0, 0, cameraVideo.videoWidth, cameraVideo.videoHeight);
if (self.onframe) {
// Comment out the line below to stop processing QR codes
await self.onframe(cameraCanvas);
}
};
var processingFrame = false;
self.onframe = async function (cameraCanvas) {
// There is a frame in the camera, what should we do with it?
if (processingFrame == false) {
processingFrame = true;
let result = await detector.detect(cameraCanvas);
processingFrame = false;
if (result === undefined || result === null || result.length === 0) {
return
};
if ('vibrate' in navigator) {
navigator.vibrate([200]);
}
cameraManager.stop();
var currentURL = new URL(window.location.href);
var newURL;
if (result[0].rawValue
&& (newURL = new URL(result[0].rawValue))
&& newURL.hostname == currentURL.hostname
&& newURL.pathname.startsWith('/pickup/qr/')
) {
window.location.href = newURL;
} else {
alert('Unsupported QR Code: ' + result[0].rawValue);
}
cameraManager.start();
}
};
};
window.addEventListener('load', function () {
var camera = new QRCodeCamera('camera');
});
})();
I also tried splitting the QR detection to a worker (worker code in Gist), but I have the same issue:
const worker = new Worker('/js/scan-worker.js');
worker.addEventListener('message', async (e) => {
if (Array.isArray(e.data)) {
var result = e.data;
if (result === undefined || result === null || result.length === 0) {
processingFrame = false;
return
};
if ('vibrate' in navigator) {
navigator.vibrate([200]);
}
var currentURL = new URL(window.location.href);
var newURL;
if (result[0].rawValue
&& (newURL = new URL(result[0].rawValue))
&& newURL.hostname == currentURL.hostname
&& newURL.pathname.startsWith('/pickup/qr/')
) {
worker.terminate();
window.location.href = newURL;
} else {
alert('Unsupported QR Code: ' + result[0].rawValue);
}
} else {
var newError = document.createElement('div');
newError.classList.add('alert', 'alert-danger');
newError.innerHTML = e.data;
errorContainer.prepend(newError);
worker.terminate();
}
processingFrame = false;
});
cameraManager.onframeready = async function (frameData) {
if (processingFrame == false) {
cameraCanvas.width = cameraVideo.videoWidth;
cameraCanvas.height = cameraVideo.videoHeight;
context.drawImage(frameData, 0, 0, cameraVideo.videoWidth, cameraVideo.videoHeight);
if (self.onframe) {
await self.onframe(cameraCanvas, context);
}
}
};
self.onframe = async function (cameraCanvas, context) {
// There is a frame in the camera, what should we do with it?
if (processingFrame == false) {
processingFrame = true;
worker.postMessage(context.getImageData(0, 0, cameraCanvas.width, cameraCanvas.height));
}
};
Not sure if this would make a difference - all the JS code is run through Laravel Mix.

How do I keep both the child process running and parent communicating in Node JS?

I'm using a blynk client written in Node JS on my raspberry pi that connects and authenticates to the blynk server. I have another process I want to run that scans for BLE beacons at the same time as keeping connected to the server and polling for button presses. I am getting them both to execute at the same time but the communication is only happening if I change the state of virtual pin "V0". I'm new to Node JS and perhaps I misunderstanding but, why does it stop my parent process once the child process authenticates and doesn't execute output the parent process unless I change the state of "V0"
//Parent Process
var Bleacon = require('./index');
var uuid = '3247ff7d3f0d4b2c9df61189398eb85e';
var arr = [];
var ledPin = 17;
var math = require('mathjs');
var child_process=require('child_process');
const child = child_process.fork("doorlock.js");
console.log("child scanning...");
Bleacon.startScanning(uuid);
Beacon()
function Beacon() {
Bleacon.on('discover', function(bleacon) {
if (bleacon.uuid == uuid) {
console.log("uuid matches");
if (bleacon.proximity == 'immediate') {
console.log('immediate: ' + bleacon.rssi);
arr.push(bleacon.rssi);
//console.log(arr);
//console.log(math.mean(arr));
if (arr.length>=20 && math.mean(arr)>=-65) {
child.send('unlock door');
arr = [];
}
} else if (bleacon.proximity == 'near') {
console.log('near: ' + bleacon.rssi);
arr.push(bleacon.rssi);
//console.log('avg rssi: ' + math.mean(arr));
//console.log(arr);
if (arr.length>=20 && math.mean(arr)<=-65) {
child.send('lock door');
arr = [];
}
} else {
arr = [];
}
}
//console.log('bleacon found: ' + JSON.stringify(bleacon));
});
}
The child process:
#!/usr/bin/env node
//Child Process
//*** SMARTPHONE DOORLOCK ***//
var unlockedState = 825;
var lockedState = 2100;
var motorPin = 18;
var buttonPin = 4;
var ledPin = 17;
var blynkToken = '191d2e5c8f754fad9af08a3b9cc81eaa';
var arr = [];
var len = 20;
var Bleacon = require('./index');
var math = require('mathjs');
var uuid = '3247ff7d3f0d4b2c9df61189398eb85e';
// *** Start code *** //
var locked = true;
//Setup servo
var Gpio = require('pigpio').Gpio,
motor = new Gpio(motorPin, {mode: Gpio.OUTPUT}),
button = new Gpio(buttonPin, {
mode: Gpio.INPUT,
pullUpDown: Gpio.PUD_DOWN,
edge: Gpio.FALLING_EDGE
}),
led = new Gpio(ledPin, {mode: Gpio.OUTPUT});
//Setup blynk
var Blynk = require('blynk-library');
var blynk = new Blynk.Blynk(blynkToken);
var v0 = new blynk.VirtualPin(0);
var v1 = new blynk.VirtualPin(1);
console.log("locking door")
lockDoor()
process.on('message', function(message) {
console.log('[child] received message from server:', message);
if (message == 'unlock door') {
console.log('I read from parent that I am to unlock the door');
}
});
button.on('interrupt', function (level) {
console.log("level: " + level + " locked: " + locked)
if (level == 0) {
if (locked) {
unlockDoor()
} else {
lockDoor()
}
}
});
v0.on('write', function(param) {
console.log('V0:', param);
if (param[0] === '0') { //unlocked
unlockDoor()
} else if (param[0] === '1') { //locked
lockDoor()
} else {
blynk.notify("Door lock button was pressed with unknown parameter");
}
});
blynk.on('connect', function() {
//console.log("Blynk ready.");
});
blynk.on('disconnect', function() { console.log("DISCONNECT"); });
function lockDoor() {
motor.servoWrite(lockedState);
led.digitalWrite(1);
locked = true
//notify
blynk.notify("Door has been locked!");
//After 1.5 seconds, the door lock servo turns off to avoid stall current
setTimeout(function(){motor.servoWrite(0)}, 1500)
}
function unlockDoor() {
motor.servoWrite(unlockedState);
led.digitalWrite(0);
locked = false
//notify
blynk.notify("Door has been unlocked!");
//After 1.5 seconds, the door lock servo turns off to avoid stall current
setTimeout(function(){motor.servoWrite(0)}, 1500)
}

Variable is null (only in Mozilla)

Here is the resume of the code:
var client = new BinaryClient('ws://localhost:9001');
var context = null;
var store_data = null;
//(.....)
if (!navigator.getUserMedia)
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia || navigator.msGetUserMedia;
if (navigator.getUserMedia) {
navigator.getUserMedia({audio:true}, success, function(e) {
alert('Error capturing audio.');
});
} else alert('getUserMedia not supported in this browser.');
function success(e) {
audioContext = window.AudioContext || window.webkitAudioContext;
context = new audioContext();
audioInput = context.createMediaStreamSource(e);
var bufferSize = 2048;
store_data = context.createScriptProcessor(bufferSize, 1, 1);
//(...)
}
//(....)
client.on('open', function() {
console.log("createStream");
Stream = client.createStream(command_list);
var recording = false;
window.startRecording = function() {
document.getElementById("startbutton").disabled = true;
document.getElementById("stopbutton").disabled = false;
recording = true;
window.Stream.resume();
}
window.stopRecording = function() {
document.getElementById("startbutton").disabled = false;
document.getElementById("stopbutton").disabled = true;
recording = false
//window.Stream.end();
window.Stream.pause();
}
store_data.onaudioprocess = function(e){ //<---line of the error
if(!recording) return;
console.log ('recording');
var left = e.inputBuffer.getChannelData(0);
window.Stream.write(convertoFloat32ToInt16(left));
}
//(..events generated from server..)
In chrome my code works just fine. In Mozilla I am getting always the error "store data is undefined". Any idea why? Because I am declaring store_data as global and when getusermedia is a sucess the value is changed.
Without knowing what calls the success function, it's difficult to say exactly, but I am fairly sure you want your client.on('open') listener to be contingent on the success function running.
I don't know how it will affect the rest of the omitted code, but I would only connect the BinaryClient when the success function has run and you are sure you have store_data defined.
function success() {
var client = new BinaryClient('ws://localhost:9001');
var context = null;
var store_data = null;
// do the original success code here
// now create that listener.
client.on('open', function() {
// do original code here
});
}
// you probably have a line of code that looks like this
navigator.getUserMedia({}, success);
Moving all of your code into the success function may work, but it won't be elegant. Once you've got the flow working, I would suggest refactoring the code, by splitting each logical bit up into its own function.
Yes it's a race. Your code must wait until getUserMedia succeeds and open is fired.
Promises are a great way to solve this:
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
(Use the above polyfill to access modern getUserMedia in all supported browsers.)
var client = new BinaryClient('ws://localhost:9001');
var context = null;
var store_data = null;
//(.....)
var haveStoreData = navigator.mediaDevices.getUserMedia({audio:true})
.then(function(stream) {
audioContext = window.AudioContext || window.webkitAudioContext;
context = new audioContext();
audioInput = context.createMediaStreamSource(stream);
var bufferSize = 2048;
return context.createScriptProcessor(bufferSize, 1, 1);
});
//(....)
client.on('open', function() {
console.log("opened");
haveStoreData.then(function(store_data) {
console.log("createStream");
Stream = client.createStream(command_list);
var recording = false;
window.startRecording = function() {
document.getElementById("startbutton").disabled = true;
document.getElementById("stopbutton").disabled = false;
recording = true;
window.Stream.resume();
};
window.stopRecording = function() {
document.getElementById("startbutton").disabled = false;
document.getElementById("stopbutton").disabled = true;
recording = false;
//window.Stream.end();
window.Stream.pause();
};
store_data.onaudioprocess = function(e){
if(!recording) return;
console.log ('recording');
var left = e.inputBuffer.getChannelData(0);
window.Stream.write(convertoFloat32ToInt16(left));
};
//(..events generated from server..)
})
.catch(function(e) { console.error(e); });
});
This will give users time to choose "Allow" in the mic permission prompt (Unlike Chrome, Firefox asks the user for permission every time, unless they choose "Always Allow").
var client = new BinaryClient('ws://193.136.94.233:9001');
var context = null;
var gain = null;
var store_data = null;
//(.....)
navigator.mediaDevices.getUserMedia({audio:true}) .then( function(stream){
context = new AudioContext();
audioInput = context.createMediaStreamSource(stream);
var bufferSize = 4096;
store_data = context.createScriptProcessor(bufferSize, 1, 1);
biquadFilter = context.createBiquadFilter();
biquadFilter.type = "lowpass";
biquadFilter.frequency.value = 11500;
biquadFilter.Q.value = 3;
ganho = context.createGain();
ganho.gain.value=0.5;
//audioInput.connect(ganho);//compresso
//ganho.connect(recorder);
//recorder.connect(context.destination);
audioInput.connect(biquadFilter);
biquadFilter.connect(ganho);
ganho.connect(store_data);
store_data.connect(context.destination);
store_data.onaudioprocess = function(e){
if(!recording){
//console.log("nada faz nada desta vida")
return;
}
console.log ('recording');
var left = e.inputBuffer.getChannelData(0);
Stream.write(convertoFloat32ToInt16(left));
}
//audioInput.connect(store_data);
} ) .catch( function(e){ console.log(e) } );
//(...)
client.on('open', function() {
console.log("opened connection");
//haveStoreData.then(function(store_data) {
Stream = client.createStream(command_list);
//recording = false;
//(........)
);
//Other function
Here is the solution to stream with BinaryJS with Chrome an Mozilla. Thanks to #jib and #Kaiido

websocket interrupted while using window.location.assign on firefox version 39

Error:
The connection to wss://localhost:28443/Administration/sessionCheck?d22c6c8e-61b4-41d3-b447-6436b5b631c9 was interrupted while the page was loading.
I am new to websocket,angular js.Using websocket in the single page - web application to understand whether the server is alive.
In this when I try use window.location.assign(url) to download the zip from the application on firefox the websocket connectivity is lost & i have tried to search this on this forum but i didn't got matched answer.
Websocket is interrupted when i use window.location.assign(url) page on firefox. This works seamless on chrome and IE.
I have also implemented the fixed on the client side by checking on window load if the socket is open or not:
Inside the controller
window.onbeforeunload = function () {
$scope.webSocketFinalize();
};
Main Controler code
function webSocketProvider($scope, $location, $window, heartbeat_interval, $translate, $timeout) {
$scope.websocketHB = null;
$scope.startWebSocketHeartBeat = function(headerValue){
var wsUri = "wss://"+window.location.host +
window.location.pathname+"severHeartBeat?"+headerValue;
var heartbeat_msg = '--heartbeat--', missed_heartbeats = 0;
websocketHB = new WebSocket(wsUri);
console.log("message 1....: startWebSocketHeartBeat"+websocketHB);
websocketHB.onopen = function(evt) {
console.log("opening...2..........");
if (heartbeat_interval === null) {
missed_heartbeats = 0;
heartbeat_interval = setInterval(function() {
try {
missed_heartbeats++;
if (missed_heartbeats >= 3){
clearInterval(heartbeat_interval);
heartbeat_interval = null;
console.log("Closing connection. Reason: ");
websocketHB.close();
window.location.href = '/Administration';
$routeParams.auth = '';
}else{
try{
if(websocketHB.readyState == 1 || websocketHB.readyState == 0){
websocketHB.send(heartbeat_msg);
}
}catch(e){}
}
} catch(e) {
clearInterval(heartbeat_interval);
heartbeat_interval = null;
console.log("Closing connection. Reason: " + e.message);
websocketHB.close();
}
}, 5000);
}
};
websocketHB.onmessage = function(evt) {
console.log("message 3....: startWebSocketHeartBeat"+evt.data);
if(evt.data == "--heartbeat--") {
missed_heartbeats = 0;
}else{
console.log("Send Failed:");
}
};
websocketHB.onerror = function(evt) {
console.log("ERROR:4 " + evt.data);
};
};
$scope.webSocketFinalize = function() {
if(null!=$scope.websocketHB){
$scope.websocketHB.close();
}
};
};

Categories

Resources