Failed connections of WebSocket remain alive - javascript

Here how my code looks like:
var ws = null;
var _open = function(address) {
ws = new WebSocket(address);
ws.onopen = onOpen;
ws.onclose = onClose;
ws.onmessage = onMessage;
ws.onerror = onError;
};
var close = function() {
if (ws) ws.close();
};
var onOpen = function() {
// do something
};
var onClose = function() {
ws = null;
retry();
};
var onError = function(event) {
ws = null;
retry();
};
var onMessage = function(event) {
// do something
};
var retry = function() {
setTimeout(function() {
// extract what I need from location.href
var address = composeWsAddress(extractHostname(location.href));
_open(address);
}, 3000);
};
WebSocketClient = {
init: function() {
var address = composeWsAddress(extractHostname(location.href));
_open(address);
}
};
It should work in this way:
at start (init) it tries to connect
if fails (onError) it tries again after 3 s
if succeeds (onOpen) and then the connection closes (onClose) it tries again after 3 s
It works but on the WebSocket server I receive a number of new connections how many times they failed. For example, I launch my client application and after 30 s start the server. Now I have about 10 connections opened (one every 3 s).
Here I read I should not take care of "delete" each instance created by new WebSocket. Anyway I set it to null when the connection fails or closes.
So why it still keeps the old instances?

Related

IndexedDB: executing function with method add several times - no new DB-entry

I have created a function to store data in indexed db:
var request = window.indexedDB.open("mynewDB", 1);
request.onupgradeneeded = function(event) {
var db = event.target.result;
var objectStore = db.createObjectStore("toDoList", {keyPath: 'key', autoIncrement: true});
var txn = event.target.transaction;
var addRequest = txn.objectStore("toDoList").add({value: storagedata});
}
(FYI: the storagedata is filled with a base64 string)
If i am executing this function via button the content of variable storagedata is in the IndexedDB. But if i want to press the button again to store another value into the IndexedDB, nothing happens.
In addition to that if i am executing the function the second time the function jumps at line request.onupgradeneeded = function(event) { in to the timeout of file "intervalTrigger-dbg.js" to code clearTimeout(this._delayedCallId);
What i did to solve the problem: debugging in browser and reading a lot of documentations about indexeddb.
I fixed the problem on my own.
For everyone who want to know how it works:
var request = window.indexedDB.open("yourDB-1", 1);
var db;
var transaction;
var store;
request.onupgradeneeded = function(event) {
var db = event.target.result;
var transaction = event.target.transaction;
var store = db.createObjectStore("yourDB", {keyPath: 'key', autoIncrement: true});
}
request.onerror = function (event) {
console.log("Here is a error: " + event.target.errorCode);
}
request.onsuccess = function (event) {
db = request.result;
transaction = db.transaction("yourDB", "readwrite");
store = transaction.objectStore("yourDB");
db.onerror = function(event){
console.log("ERROR" + event.target.errorCode);
}
store.put({value: storagedata});
transaction.complete = function() {
db.close();
}
}

How to update object in IndexedDB from service worker

I'm trying to update an Object Store in IndexedDB from a Service Worker, this is my code right now:
function updateUrlLink(url_link) {
var request = indexedDB.open('db', 1);
var url_link_value = url_link;
request.onsuccess = function (event) {
var store = request.result.transaction("url_link", "readwrite").objectStore("url_link");
store.add(url_link_value, "url_link");
};
request.onupgradeneeded = function (event) {
var db = event.target.result;
var store = db.createObjectStore('url_link');
};
}
Is this the right way to update url_link or is there other way?

backbone.js sync using websocket

I'm trying to use WebSocket for replacing Backbone.sync method.
Then I created three instance of "Sample" model named sample1, sample2 and sample3 and call fetch() method. Each request was successfully sent to the server.
However, when response data coming from the server, every response is set to the sample1. In other word, backbone.js triggered change event and only sample1 instance catch it.
I know there's good library named backbone.WS. However i would like to know why below code didn't work properly. Please give me any comments.
$(document).ready(function() {
var ws;
var url = ws://localhost:8080/application/sample;
Backbone.sync = function(method, model, options) {
var data = JSON.stringify({
'method' : method,
'data' : model.attributes}
);
if(ws == null) {
console.log("Create a new connection to the server.");
ws = new WebSocket(url);
console.log("Binding callback methods.");
ws.onopen = onOpen;
ws.onmessage = onMessage;
ws.onclose = onClose;
ws.onerror = onError;
}
function send(message) {
// Wait until the state of the socket is not ready and send the message when it is...
waitForSocketConnection(ws, function(){
console.log("message sent!!!");
ws.send(message);
});
}
// Make the function wait until the connection is made...
function waitForSocketConnection(socket, callback){
setTimeout(
function () {
if (socket.readyState === 1) {
console.log("Connection is made")
if(callback != null){
callback();
}
return;
} else {
console.log("Waiting for connecting...")
waitForSocketConnection(socket, callback);
}
}, 10); // wait 5 milisecond for the connection...
}
function onOpen(event) {
console.info("Connection established to " + url);
};
function onMessage(event) {
console.info("Message Received!");
var message = JSON.parse(event.data);
console.log("model: " + JSON.stringify(model.attributes));
model.set(message);
};
function onClose(event) {
console.log(event.code);
};
function onError() {
console.warn("There was an error with your websocket.");
}
send(data);
console.log("Request is sent to the server.");
options.success(message);
};
var Sample = Backbone.Model.extend({
defaults : {
id : 0,
name : "default"
}
});
var sample1 = new Sample({id:1});
var sample2 = new Sample({id:2});
var sample3 = new Sample({id:3});
sample1.fetch();
sample2.fetch();
sample3.fetch();
sample1.on("change", function(model) {
console.log("--- onChange method in sample 1");
});
sample2.on("change", function(model) {
console.log("+++ onChange method in sample 2");
});
sample3.on("change", function(model) {
console.log("=== onChange method in sample 3");
});
}

Javascript call method in another method

Now I'm trying to implement Unity Webgl with jslib. I'm so confused about how to call method in another method's function. I want to call method Recv when message was coming (ws.onmessage). But, it show "TypeError: this.Recv is undefined". Could you please help me figure out this source? Thank you !!!!!
Here's my source code
var ws = null;
var init_url = "";
var received_msg = "";
var error_msg = "";
var WebsocketLib = {
Hello: function(){
window.alert("Hello,world!");
},
InitSocket: function(url){
init_url = Pointer_stringify(url);
console.log("InitWebSocket: "+init_url);
ws = new WebSocket(init_url);
ws.onopen = function(evt){
console.log("Connect");
isConnected = false;
ws.send("hello");
};
ws.onclose = function(evt) {
console.log("Close");
isConnected = false;
};
ws.onmessage = function(evt) {
received_msg = evt.data;
console.log("[recv] "+received_msg);
this.Recv.call(this);
};
ws.onerror = function(evt) {
error_msg = evt.data;
console.log("[error] "+error_msg);
this.Error.call(this);
};
},
Recv: function(){
console.log("[recv] "+received_msg);
var buffer = _malloc(received_msg.length + 1);
writeStringToMemory(returnStr, buffer);
return buffer;
},
Error: function(){
console.log("[error] "+error_msg);
var buffer = _malloc(error_msg.length + 1);
writeStringToMemory(error_msg, buffer);
return buffer;
}
}
Inside of ws.onmessage this will refer to ws (as we're inside a method of ws) and not WebsocketLib.
However, inside Initsocket, where you define the handlers, this would correctly (in the sense that this is what you want) refer to the WebsocketLib object, so you can create a bound function to bind the outer this value to be used as this inside the event handler, like this:
ws.onmessage = function(evt) {
received_msg = evt.data;
console.log("[recv] "+received_msg);
this.Recv.call(this);
}.bind(this);
in JavaScript the value of this behaves differently than in other languages. Its value depends on how the function is called. You can read more about it in the Mozilla MDN page.
To solve your specific problem you can:
InitSocket: function(url){
var that = this; // [1]
init_url = Pointer_stringify(url);
console.log("InitWebSocket: "+init_url);
ws = new WebSocket(init_url);
ws.onopen = function(evt){
console.log("Connect");
isConnected = false;
ws.send("hello");
};
ws.onclose = function(evt) {
console.log("Close");
isConnected = false;
};
ws.onmessage = function(evt) {
received_msg = evt.data;
console.log("[recv] "+received_msg);
that.Recv.call(that); // [2]
};
ws.onerror = function(evt) {
error_msg = evt.data;
console.log("[error] "+error_msg);
that.Error.call(that); // [2]
};
},
In line 1 I bind the this variable to a custom variable that I decided to call that (but you can call it as you want). Then in line 2 I used that instead of this.
Inside the ws.onmessage function the value of this is not referring to the instance of WebsocketLib, so you need to use this "trick" and access the right this value using the one saved in the closure, inside the value of that.

Use HTTP-on-modify-request to redirect URL

I am building an add-on for Firefox that redirect request to a new URL if the URL match some conditions. I've tried this, and it does not work.
I register an observer on HTTP-on-modify-request to process the URL, if the URL match my condition, I will redirect to a new URL.
Here is my code:
var Cc = Components.classes;
var Ci = Components.interfaces;
var Cr = Components.results;
var newUrl = "https://google.com";
function isInBlacklist(url) {
// here will be somemore condition, I just use youtube.com to test
if (url.indexOf('youtube.com') != -1) {
return true;
}
return false;
}
exports.main = function(options,callbacks) {
// Create observer
httpRequestObserver =
{
observe: function (subject, topic, data) {
if (topic == "http-on-modify-request") {
var httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
var uri = httpChannel.URI;
var domainLoc = uri.host;
if (isInBlacklist(domainLoc) === true) {
httpChannel.cancel(Cr.NS_BINDING_ABORTED);
var gBrowser = utils.getMostRecentBrowserWindow().gBrowser;
var domWin = channel.notificationCallbacks.getInterface(Ci.nsIDOMWindow);
var browser = gBrowser.getBrowserForDocument(domWin.top.document);
browser.loadURI(newUrl);
}
}
},
register: function () {
var observerService = Cc["#mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
observerService.addObserver(this, "http-on-modify-request", false);
},
unregister: function () {
var observerService = Cc["#mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
observerService.removeObserver(this, "http-on-modify-request");
}
};
//register observer
httpRequestObserver.register();
};
exports.onUnload = function(reason) {
httpRequestObserver.unregister();
};
I am new to Firefox add-on development.
You can redirect a channel by calling nsIHttpChannel.redirectTo.
This is not possible once the channel is opened, but in http-on-modify-request it will work.
So in your code, you can do something like:
Cu.import("resource://gre/modules/Services.jsm");
// ...
if (condition) {
httpChannel.redirectTo(
Services.io.newURI("http://example.org/", null, null));
}
It looks like you might be using the Add-on SDK. In that case, read up on Using Chrome Authority.
You could simply do a
httpChannel.URI.spec = newUrl;
instead of
httpChannel.cancel(Cr.NS_BINDING_ABORTED);
...
browser.loadURI(newUrl);
Not sure how 'safe' it would be in your case, since I'm not exactly sure how other headers in the request (e.g. Cookie) would be manipulated when you change the URL to point to an entirely different domain at this stage.

Categories