I have a page and an iframe inside of the page. Both hosted on the same domain. I have a full control of the iframe, but don't have a control of the parent page.
So I need to establish a websocket connection from the iframe, but in context of the parent window and keep it alive while I'm navigating out of the iframe (to the other menu items of the parent page).
(see the image) Like establishing connection in A.html, and keep it alive while navigating to B and C.
is that possible?
Short answer:
Direct script injection to the parent window still might be a more elegant solution.
Long answer:
Websocket is just a kind of connection to the server. Once you create it - it persists in your browser's tab and it's not destroyed if you unload the script which created the websocket.
Two issues with creating websockets within iframes:
You can try to create a websocket factory on the main window. The instance of this factory would be responsible for:
There are some known issues with function cloning - ie, if they use outer closure defined in iframe's script - that closure will be lost. You may want to do a research on cloning libraries.
main.js (loaded in main index.html):
var socketsCollection = new SocketsCollection();
function SocketsCollection() {
this.collection = {};
this.add = function(key, obj) {
if (this.exists(key)) return;
// clone websocket event handlers
// PS: this is not the best solution to clone a function. Need a better research here
eval("var onopen = " + obj.onopen.toString());
eval("var onclose = " + obj.onclose.toString());
eval("var onmessage = " + obj.onmessage.toString());
// create websocket
var ws = new WebSocket(obj.url);
ws.onopen = function(e) {
onopen(e, key, ws);
};
ws.onclose = function(e) {
onclose(e, key, ws);
}
ws.onmessage = function(e) {
onmessage(e, key, ws);
}
this.collection[key] = {
key: key,
ws: ws
};
// test websocket is alive
var self = this;
var counter = 1;
window.setInterval(function () {
console.log('testing ' + key);
self.collection[key].ws.send('ping # ' + counter + ' websocket ' + key);
counter++;
}, 2000);
}
this.exists = function(key){
return this.collection[key] !== undefined;
}
}
iframed.js:
function foo(window, socketKey) {
if (window.socketsCollection.exists(socketKey)) return;
var newSocketData = {
url: "wss://echo.websocket.org/",
onopen: function(e, key, ws) {
console.log(key + ' is OPEN', ws.readyState)
ws.send('Hello socket ' + key);
},
onclose: function(e, key, ws) {
console.log(key + ' is CLOSED', ws.readyState)
},
onmessage: function (e, key, ws) {
console.log(key + ' response: ', e.data);
}
};
window.socketsCollection.add(socketKey, newSocketData);
}
a.html:
<script src="iframed.js"></script>
<script>
foo.call(window.parent, window.parent, 'A');
</script>
b.html:
<script src="iframed.js"></script>
<script>
foo.call(window.parent, window.parent, 'B');
</script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With