I'm trying to connect at asterisk websocket, using socket.io-client
socket = io.connect(url ,{
transports: ['websocket'],
secure: true,
'force new connection' : false,
'reconnect' : true,
});
It works, but everytime I change or refresh page, websocket connection disconnect and reconnect (obviusly). My app is not "one-page-app".
There is a way for keep connection alive?
There is a way for keep connection alive?
No. Not if you allow the page to change in the browser.
When the browser changes pages, it will close all resources associated with the old page (including webSockets) and then it will initialize and open the new page. You cannot change that.
The only way to keep a webSocket open is to put it in a window that does not change. That would entail either converting to a single page app (that doesn't change pages) or putting the webSocket in a frame or window that doesn't change. You could have the user install a browser extension (which can maintain persistent connections), but I assume that isn't what you're asking about.
Otherwise, you have to just manage things on your server to handle the fact that a page change within your site will close the old webSocket and open a new one.
Related
I'm developing a Firefox extension based on Addon SDK.
Inside my content script, I need to create WebSocket connection to my localhost server using wss.
In my addon script (index.js), I use "sdk/tabs" to inject content script.
var tabs = require("sdk/tabs");
tabs.on("ready", function(tab){
var worker = tab.attach({
contentScriptFile: ["./websocket.js"]
});
});
data/websocket.js looks like:
websocket = new WebSocket("wss://localhost:8443/WebsocketServer/");
websocket.onopen = function(evt){
console.log("connection open");
websocket.send("connection established!");
};
websocket.onmessage = function(evt){
console.log("message received: "+evt.data);
};
I open firefox and open a page with https://localhost:8443/ and accept the certificate. So the certificate won't be a problem here.
I can open a normal http page and this addon works perfectly, talks to my websocket server. Also I can make it work if I open https://google.com.
But when I open https://www.facebook.com or https://www.twitter.com, the websocket connection cannot be established.
When I turn on developer console, i can see error message:
Content Security Policy: The page's settings blocked the loading of a
resource at wss://localhost:8443/WebsocketServer/ ("connect-src
https://graph.facebook.com https://*.giphy.com https://pay.twitter.com
https://analytics.twitter.com https://media.riffsy.com
https://upload.twitter.com https://api.mapbox.com https://twitter.com").
Content Security Policy: The page's settings blocked the loading of a
resource at wss://localhost:8443/WebsocketServer/ ("connect-src
https://*.facebook.com https://*.fbcdn.net https://*.facebook.net
https://*.spotilocal.com:* https://*.akamaihd.net wss://*.facebook.com:*
https://fb.scanandcleanlocal.com:* https://*.atlassolutions.com
https://attachment.fbsbx.com ws://localhost:* blob:").
After I check, find facebook and twitter both implement the content script policy in their http header:
https://developer.mozilla.org/en-US/docs/Web/Security/CSP/Introducing_Content_Security_Policy
But I think this policy should be exempted for addon. How could I bypass this check and make my websocket connection also work on facebook and twitter also?
I found there is one link that uses XPCOMM to hyjack http header and bypass the CSP check, but this is not I'm looking for, as XPCOMM will be deprecated by firefox. Is there a more proper way of doing this?
Thanks a lot!
I'm using SignalR 2 and I'm having problems when I open multiple tabs of the same page. After opening 4 or 5 tabs, all the requests get in pending status, like if I had exceeded the maximum allowed by the browser. If I close a few tabs, everything works again. Even with all the tabs opened, if I open a different browser it works. This happens both in Chrome and Firefox. If I disable SignalR, I can open as many tabs as I want.
This is my code:
// Reference the auto-generated proxy for the hub.
notificator.hub = $.connection.messageHub;
// Create a function that the hub can call back to display messages.
notificator.hub.client.refreshNotifications = function () {
// business code
};
$.connection.hub.start().done(function () {
notificator.hubStarted = true;
});
$.connection.hub.disconnected(function () {
notificator.hubStarted = false;
setTimeout(function () {
$.connection.hub.start();
}, 2000); // Restart connection after 2 seconds.
});
If I remove the handler for disconnected event, the problem persists. The notification system works correctly so SignalR is doing its job but it's causing me issues in the app. It's even slower.
I found two solutions:
1) In my case, it's an intranet web application so I know that everybody supports WebSockets and WebSockets doesn't have the connection limitation. But, why this was not working? well, first I added logging to SignalR by adding this line:
$.connection.hub.logging = true;
Then I tried to force using WebSockets:
$.connection.hub.start({ transport: 'webSockets' }).done(function () { .. });
But, checking the logs I found out that WebSockets were not supported because they were not installed in the server. So, I followed these steps in Windows 2012 and installed it:
Open Server Manager.
Under the Manage menu, click Add Roles and Features.
Select Role-based or Feature-based Installation, and then click
Next.
Select the appropriate server, (your local server is selected by
default), and then click Next.
Expand Web Server (IIS) in the Roles tree, then expand Web Server,
and then expand Application Development.
Select WebSocket Protocol, and then click Next.
Click Install.
Source: http://www.iis.net/learn/get-started/whats-new-in-iis-8/iis-80-websocket-protocol-support
After that, everything worked. In Chrome, under Network tab, you'll find a WS filter. Click on it and you should see the websocket.
2) Using IWC-SignalR:
https://github.com/slimjack/IWC-SignalR
It works this way:
One of the windows becomes a connection owner (choosen randomly) and
holds the real SignalR connection. If connection owner is closed or
crashed another window becomes a connection owner - this happens
automatically. Inter-window communication is done by means of IWC.
I have long poll Ajax request. Browser, at least but not last IE doesn't terminate the request at page leaving, so request remains open and active even if a user visits some other site. Say more, a browser can successfully process responses from this connection, although their result go nowhere. General recommendations as call htmlxml connection abort or stop for a window obviously do not work.
So my implementation is adding extra Ajax call on unload to notify server connection holder that page is on leave, so it can send some dummy response and a browser will return the connection to pool of available after. This approach works but looks for me over engineered. Unfortunately I can observe a similar problem with some other programs, like GMAIL, it also does long poll and as result after some reloading it stops working. So if somebody found some good approach to address the problem without switching to short poll or assign connection timeout, then share your solution.
There's an abort() method on IE's XHR which will manually disconnect it.
It's a bit hacky, but you could try something like:
<body onbeforeunload="AbortMyAjax()">
and use that method to abort any active long-polls.
For reference, here's a bit of code from a project of mine:
$this.lp = null;
function _LongPoll() {
$.ajaxSetup({ cache: false });
$this.lp = $.getJSON(m_PollUrl, _LongPollCallback);
}
And in the body beforeunload:
if(!!QueueManager.lp && !!QueueManager.lp.abort) QueueManager.lp.abort('PAGE_CLOSED');
I'm building a website with mvc3 and I need to delete a data in my database only when the application is closing. (The user click on the red x).
I tried with javascript using the onbeforeunload event, but this event happens everytime I go into a new page in my application.
Is it possible to detect when the user closes the window?
It's not possible. But, what you can do is have a small javascript block that will make an ajax call every n minutes/seconds to tell the server that the user still has the browser open.
This way, you can set a timeout that says if after 5 minutes we haven't heard from the user we can delete the data in the database (or whatever action you need to do).
To implement the timeout logic there are 2 options:
You have a separate service (console app or windows service) running on some interval that checks if any user's timeout is greater than some value. If it is then perform whatever action you need.
If any user performs an action that would have been blocked, you first check if any user still has it active (the timeout value is greater than current time). If there is, you block the user, if there isn't, you can remove that old timeout value since it's expired.
Use a synchronous ajax request in the window.unload event.
When the user goes to a different page, or closes, or refreshes then this event will fire. You could call a service on your web app to notify it that the user is no longer editing the document
After a very quick google, I saw this snippet here
$(window).unload(function() {
$.ajax({
url: 'resetTheDocument?id=whatever',
async: false,
cache: false,
type: "POST",
data: "My work here is done"
});
});
Good morning you could try adding your logic to the global.asax file in the Session_End method to delete the record in your database.
I am trying to prevent the client from disconnecting from the server. So before the user closes the window on which the app is open, I do:
$(window).bind("beforeunload", function() {
return("Close the app?");
});
But the problem is that no matter if the user chooses to leave or stay on the page where the app is open, the client get's disconnected (stops listening) from the server, before even I chose an option. So if the user chooses to stay on the page, nothing will be sent or received from the server.
Why can this be? How can this be prevented?
I had exactly the same problem in my project.
When you call socket.connect(), you should set sync disconnect on unload parameter of your connection to false (it is true by default):
var conn_options = {
'sync disconnect on unload':false
};
socket = io.connect(url, conn_options);
You can find more connection options here: https://github.com/LearnBoost/socket.io/wiki/Configuring-Socket.IO
P.S. Hope it's still actual for you :)
UPD.
Since the doc was changed, false is now the default value of sync disconnect on unload
You might not be able to avoid the problem as there are no other events triggering before "beforeunload" at window close that i know of. However,you could work around it by asking the socket to reconnect in the callback of the window close dialog when the user chooses to not exit the page. Reconnecting is pretty easy, just:
socket.connect()
Here's another question that describes reconnecting in more detail:
How to reconnect as soon as disconnect happens